diff --git a/404.html b/404.html new file mode 100644 index 00000000..641e10be --- /dev/null +++ b/404.html @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + +404 Page not found | Luet + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+ +
+
+

Not found

+

Oops! This page doesn't exist. Try going back to our home page.

+ +

You can learn how to make a 404 page like this in Custom 404 Pages.

+
+
+ +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 00000000..881e12c1 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +luet.io diff --git a/about/featured-background.jpg b/about/featured-background.jpg new file mode 100644 index 00000000..fab5c23e Binary files /dev/null and b/about/featured-background.jpg differ diff --git a/about/featured-background_hu3d03a01dcc18bc5be0e67db3d8d209a6_806797_1920x1080_fill_q75_catmullrom_bottom.jpg b/about/featured-background_hu3d03a01dcc18bc5be0e67db3d8d209a6_806797_1920x1080_fill_q75_catmullrom_bottom.jpg new file mode 100644 index 00000000..1d3e48b6 Binary files /dev/null and b/about/featured-background_hu3d03a01dcc18bc5be0e67db3d8d209a6_806797_1920x1080_fill_q75_catmullrom_bottom.jpg differ diff --git a/about/featured-background_hu3d03a01dcc18bc5be0e67db3d8d209a6_806797_960x540_fill_q75_catmullrom_bottom.jpg b/about/featured-background_hu3d03a01dcc18bc5be0e67db3d8d209a6_806797_960x540_fill_q75_catmullrom_bottom.jpg new file mode 100644 index 00000000..40497407 Binary files /dev/null and b/about/featured-background_hu3d03a01dcc18bc5be0e67db3d8d209a6_806797_960x540_fill_q75_catmullrom_bottom.jpg differ diff --git a/about/index.html b/about/index.html new file mode 100644 index 00000000..330feafb --- /dev/null +++ b/about/index.html @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + + +About Luet | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

About Luet

+ +
+ + + +

Luet is a Package Manager which uses Containers technologies. +

+ + + +
+
+
+
+
+ +
+ + + + + + + +
+
+ + +

Luet uses Container technologies ( Docker, img ) to build packages. +It provides an abstraction over the Dockerfile format introducing relation and versioning of images.

+ + +
+
+
+ + + + + + + + +
+
+
+ + +
+

Zero-deps installer

+
The installer can run in "from scratch" environment - your system will be always recoverable - everything which was built from containers can be installed locally. +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + +
+

In few commands it allows you to switch between multiple Linux Distributions, in runtime!

+
+ + + +
+
+
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/about/index.xml b/about/index.xml new file mode 100644 index 00000000..d90f5289 --- /dev/null +++ b/about/index.xml @@ -0,0 +1,17 @@ + + + Luet – About Luet + https://luet-lab.github.io/docs/about/ + Recent content in About Luet on Luet + Hugo -- gohugo.io + + + + + + + + + + + diff --git a/blog/2019/12/23/0.3-release/index.html b/blog/2019/12/23/0.3-release/index.html new file mode 100644 index 00000000..5adf0a77 --- /dev/null +++ b/blog/2019/12/23/0.3-release/index.html @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + +0.3 Release | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + RSS + + +
+

0.3 Release

+
X-Mas release!
+ + +

This release comes with a lot of bugfixes and enhancement to the SAT solver core:

+
    +
  • Add support for provides. They allow to have virtual packages which can be replaced during solving by other drop-in packages.
  • +
  • Tons of fixes
  • +
  • Preparation for upcoming compression support
  • +
+ + + + + +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blog/2019/12/23/website-is-up/index.html b/blog/2019/12/23/website-is-up/index.html new file mode 100644 index 00000000..d3b8d998 --- /dev/null +++ b/blog/2019/12/23/website-is-up/index.html @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + +Website is up | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + RSS + + +
+

Website is up

+
Website is up
+ + +

Finally the website is up! Docs are a work in progress. Stay tuned for more upcoming updates

+ + + + + +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blog/index.html b/blog/index.html new file mode 100644 index 00000000..5bebc7df --- /dev/null +++ b/blog/index.html @@ -0,0 +1,413 @@ + + + + + + + + + + + + + + + + + + + + + +Luet Blog | Luet + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + RSS + + + + + + +
+
+ +

Posts in 2019

+
    + +
  • +
    +
    Website is up
    +

    Monday, December 23, 2019 in News

    + + + + + + + +

    Finally the website is up! Docs are a work in progress. Stay tuned for more upcoming updates +

    +

    Read more

    +
    +
  • + +
  • +
    +
    0.3 Release
    +

    Monday, December 23, 2019 in Releases

    + + + + + + + +

    This release comes with a lot of bugfixes and enhancement to the SAT solver core: + Add support for provides. They allow to have virtual packages which can be replaced during solving by other drop-in packages. Tons of fixes Preparation for upcoming …

    +

    Read more

    +
    +
  • + +
+ + +
+
+
+
+ + + +
+
+ +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blog/index.xml b/blog/index.xml new file mode 100644 index 00000000..3e1ef998 --- /dev/null +++ b/blog/index.xml @@ -0,0 +1,50 @@ + + + Luet – Luet Blog + https://luet-lab.github.io/docs/blog/ + Recent content in Luet Blog on Luet + Hugo -- gohugo.io + + + + + + + + + + + Blog: 0.3 Release + https://luet-lab.github.io/docs/blog/2019/12/23/0.3-release/ + Mon, 23 Dec 2019 00:00:00 +0000 + + https://luet-lab.github.io/docs/blog/2019/12/23/0.3-release/ + + + + <p>This release comes with a lot of bugfixes and enhancement to the SAT solver core:</p> +<ul> +<li>Add support for <code>provides</code>. They allow to have <code>virtual</code> packages which can be replaced during solving by other drop-in packages.</li> +<li>Tons of fixes</li> +<li>Preparation for upcoming compression support</li> +</ul> + + + + + + Blog: Website is up + https://luet-lab.github.io/docs/blog/2019/12/23/website-is-up/ + Mon, 23 Dec 2019 00:00:00 +0000 + + https://luet-lab.github.io/docs/blog/2019/12/23/website-is-up/ + + + + <p>Finally the website is up! Docs are a work in progress. Stay tuned for more upcoming updates</p> + + + + + + diff --git a/blog/news/index.html b/blog/news/index.html new file mode 100644 index 00000000..9714fdb7 --- /dev/null +++ b/blog/news/index.html @@ -0,0 +1,380 @@ + + + + + + + + + + + + + + + + + + + + + +News About Luet | Luet + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + RSS + + + + + + +
+
+ +

Posts in 2019

+
    + +
  • +
    +
    Website is up
    +

    Monday, December 23, 2019 in News

    + + + + + + + +

    Finally the website is up! Docs are a work in progress. Stay tuned for more upcoming updates +

    +

    Read more

    +
    +
  • + +
+ + +
+
+
+
+ + + +
+
+ +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blog/news/index.xml b/blog/news/index.xml new file mode 100644 index 00000000..6a294957 --- /dev/null +++ b/blog/news/index.xml @@ -0,0 +1,31 @@ + + + Luet – News About Luet + https://luet-lab.github.io/docs/blog/news/ + Recent content in News About Luet on Luet + Hugo -- gohugo.io + + + + + + + + + + + Blog: Website is up + https://luet-lab.github.io/docs/blog/2019/12/23/website-is-up/ + Mon, 23 Dec 2019 00:00:00 +0000 + + https://luet-lab.github.io/docs/blog/2019/12/23/website-is-up/ + + + + <p>Finally the website is up! Docs are a work in progress. Stay tuned for more upcoming updates</p> + + + + + + diff --git a/blog/news/page/1/index.html b/blog/news/page/1/index.html new file mode 100644 index 00000000..ee20e81e --- /dev/null +++ b/blog/news/page/1/index.html @@ -0,0 +1 @@ +https://luet-lab.github.io/docs/blog/news/ \ No newline at end of file diff --git a/blog/page/1/index.html b/blog/page/1/index.html new file mode 100644 index 00000000..b76564df --- /dev/null +++ b/blog/page/1/index.html @@ -0,0 +1 @@ +https://luet-lab.github.io/docs/blog/ \ No newline at end of file diff --git a/blog/releases/index.html b/blog/releases/index.html new file mode 100644 index 00000000..0645a750 --- /dev/null +++ b/blog/releases/index.html @@ -0,0 +1,380 @@ + + + + + + + + + + + + + + + + + + + + + +New Releases | Luet + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + RSS + + + + + + +
+
+ +

Posts in 2019

+
    + +
  • +
    +
    0.3 Release
    +

    Monday, December 23, 2019 in Releases

    + + + + + + + +

    This release comes with a lot of bugfixes and enhancement to the SAT solver core: + Add support for provides. They allow to have virtual packages which can be replaced during solving by other drop-in packages. Tons of fixes Preparation for upcoming …

    +

    Read more

    +
    +
  • + +
+ + +
+
+
+
+ + + +
+
+ +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blog/releases/index.xml b/blog/releases/index.xml new file mode 100644 index 00000000..3bc29be9 --- /dev/null +++ b/blog/releases/index.xml @@ -0,0 +1,36 @@ + + + Luet – New Releases + https://luet-lab.github.io/docs/blog/releases/ + Recent content in New Releases on Luet + Hugo -- gohugo.io + + + + + + + + + + + Blog: 0.3 Release + https://luet-lab.github.io/docs/blog/2019/12/23/0.3-release/ + Mon, 23 Dec 2019 00:00:00 +0000 + + https://luet-lab.github.io/docs/blog/2019/12/23/0.3-release/ + + + + <p>This release comes with a lot of bugfixes and enhancement to the SAT solver core:</p> +<ul> +<li>Add support for <code>provides</code>. They allow to have <code>virtual</code> packages which can be replaced during solving by other drop-in packages.</li> +<li>Tons of fixes</li> +<li>Preparation for upcoming compression support</li> +</ul> + + + + + + diff --git a/blog/releases/page/1/index.html b/blog/releases/page/1/index.html new file mode 100644 index 00000000..951d9ce5 --- /dev/null +++ b/blog/releases/page/1/index.html @@ -0,0 +1 @@ +https://luet-lab.github.io/docs/blog/releases/ \ No newline at end of file diff --git a/community/index.html b/community/index.html new file mode 100644 index 00000000..5b1b4bb1 --- /dev/null +++ b/community/index.html @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + +Community | Luet + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+ + + +
+
+ +

Join the Luet community

+ +

Luet is an open source project that anyone in the community can use, improve, and enjoy. We'd love you to join us! Here's a few ways to find out what's happening and get involved. + +

+
+ + + + + + + +
+ + +
+ + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/community/index.xml b/community/index.xml new file mode 100644 index 00000000..5ec00139 --- /dev/null +++ b/community/index.xml @@ -0,0 +1,17 @@ + + + Luet – Community + https://luet-lab.github.io/docs/community/ + Recent content in Community on Luet + Hugo -- gohugo.io + + + + + + + + + + + diff --git a/css/prism.css b/css/prism.css new file mode 100644 index 00000000..f55c4c6e --- /dev/null +++ b/css/prism.css @@ -0,0 +1,208 @@ +/* PrismJS 1.21.0 +https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+c+csharp+cpp+go+java+markdown+python+scss+sql+toml+yaml&plugins=toolbar+copy-to-clipboard */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + background: none; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + font-size: 1em; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.token.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol, +.token.deleted { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #9a6e3a; + /* This background color was intended by the author of this theme. */ + background: hsla(0, 0%, 100%, .5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function, +.token.class-name { + color: #DD4A68; +} + +.token.regex, +.token.important, +.token.variable { + color: #e90; +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} + +div.code-toolbar { + position: relative; +} + +div.code-toolbar > .toolbar { + position: absolute; + top: .3em; + right: .2em; + transition: opacity 0.3s ease-in-out; + opacity: 0; +} + +div.code-toolbar:hover > .toolbar { + opacity: 1; +} + +/* Separate line b/c rules are thrown out if selector is invalid. + IE11 and old Edge versions don't support :focus-within. */ +div.code-toolbar:focus-within > .toolbar { + opacity: 1; +} + +div.code-toolbar > .toolbar .toolbar-item { + display: inline-block; +} + +div.code-toolbar > .toolbar a { + cursor: pointer; +} + +div.code-toolbar > .toolbar button { + background: none; + border: 0; + color: inherit; + font: inherit; + line-height: normal; + overflow: visible; + padding: 0; + -webkit-user-select: none; /* for button */ + -moz-user-select: none; + -ms-user-select: none; +} + +div.code-toolbar > .toolbar a, +div.code-toolbar > .toolbar button, +div.code-toolbar > .toolbar span { + color: #bbb; + font-size: .8em; + padding: 0 .5em; + background: #f5f2f0; + background: rgba(224, 224, 224, 0.2); + box-shadow: 0 2px 0 0 rgba(0,0,0,0.2); + border-radius: .5em; +} + +div.code-toolbar > .toolbar a:hover, +div.code-toolbar > .toolbar a:focus, +div.code-toolbar > .toolbar button:hover, +div.code-toolbar > .toolbar button:focus, +div.code-toolbar > .toolbar span:hover, +div.code-toolbar > .toolbar span:focus { + color: inherit; + text-decoration: none; +} + diff --git a/css/shortcodes.css b/css/shortcodes.css new file mode 100644 index 00000000..0aa1c0f8 --- /dev/null +++ b/css/shortcodes.css @@ -0,0 +1,2 @@ +@import "shortcodes/tabbed-pane.css"; +@import "shortcodes/cards-pane.css"; diff --git a/css/shortcodes/cards-pane.css b/css/shortcodes/cards-pane.css new file mode 100644 index 00000000..34c85450 --- /dev/null +++ b/css/shortcodes/cards-pane.css @@ -0,0 +1,21 @@ +.card-deck { + max-width: 83%; +} + +.card { + max-width: 80%; +} + +.card-body.code { + background-color: #f8f9fa; + padding: 0 0 0 1ex; +} + +.card-body pre { + margin: 0; + padding: 0 1rem 1rem 1rem; +} + +.card .highlight { + border: none; +} diff --git a/css/shortcodes/tabbed-pane.css b/css/shortcodes/tabbed-pane.css new file mode 100644 index 00000000..30163987 --- /dev/null +++ b/css/shortcodes/tabbed-pane.css @@ -0,0 +1,18 @@ +.td-content .highlight { + margin: 0rem 0 2rem 0; +} + +.tab-content .highlight { + border: none; +} + +.tab-content { + margin: 0rem; + max-width: 80%; +} + +.tab-content pre { + border-left: 1px solid rgba(0, 0, 0, 0.125); + border-right: 1px solid rgba(0, 0, 0, 0.125); + border-bottom: 1px solid rgba(0, 0, 0, 0.125); +} diff --git a/css/swagger-ui.css b/css/swagger-ui.css new file mode 100644 index 00000000..c61e5a85 --- /dev/null +++ b/css/swagger-ui.css @@ -0,0 +1,4 @@ +.swagger-ui{ + /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */font-family:sans-serif;color:#3b4151}.swagger-ui html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}.swagger-ui body{margin:0}.swagger-ui article,.swagger-ui aside,.swagger-ui footer,.swagger-ui header,.swagger-ui nav,.swagger-ui section{display:block}.swagger-ui h1{font-size:2em;margin:.67em 0}.swagger-ui figcaption,.swagger-ui figure,.swagger-ui main{display:block}.swagger-ui figure{margin:1em 40px}.swagger-ui hr{box-sizing:content-box;height:0;overflow:visible}.swagger-ui pre{font-family:monospace,monospace;font-size:1em}.swagger-ui a{background-color:transparent;-webkit-text-decoration-skip:objects}.swagger-ui abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.swagger-ui b,.swagger-ui strong{font-weight:inherit;font-weight:bolder}.swagger-ui code,.swagger-ui kbd,.swagger-ui samp{font-family:monospace,monospace;font-size:1em}.swagger-ui dfn{font-style:italic}.swagger-ui mark{background-color:#ff0;color:#000}.swagger-ui small{font-size:80%}.swagger-ui sub,.swagger-ui sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.swagger-ui sub{bottom:-.25em}.swagger-ui sup{top:-.5em}.swagger-ui audio,.swagger-ui video{display:inline-block}.swagger-ui audio:not([controls]){display:none;height:0}.swagger-ui img{border-style:none}.swagger-ui svg:not(:root){overflow:hidden}.swagger-ui button,.swagger-ui input,.swagger-ui optgroup,.swagger-ui select,.swagger-ui textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}.swagger-ui button,.swagger-ui input{overflow:visible}.swagger-ui button,.swagger-ui select{text-transform:none}.swagger-ui [type=reset],.swagger-ui [type=submit],.swagger-ui button,.swagger-ui html [type=button]{-webkit-appearance:button}.swagger-ui [type=button]::-moz-focus-inner,.swagger-ui [type=reset]::-moz-focus-inner,.swagger-ui [type=submit]::-moz-focus-inner,.swagger-ui button::-moz-focus-inner{border-style:none;padding:0}.swagger-ui [type=button]:-moz-focusring,.swagger-ui [type=reset]:-moz-focusring,.swagger-ui [type=submit]:-moz-focusring,.swagger-ui button:-moz-focusring{outline:1px dotted ButtonText}.swagger-ui fieldset{padding:.35em .75em .625em}.swagger-ui legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}.swagger-ui progress{display:inline-block;vertical-align:baseline}.swagger-ui textarea{overflow:auto}.swagger-ui [type=checkbox],.swagger-ui [type=radio]{box-sizing:border-box;padding:0}.swagger-ui [type=number]::-webkit-inner-spin-button,.swagger-ui [type=number]::-webkit-outer-spin-button{height:auto}.swagger-ui [type=search]{-webkit-appearance:textfield;outline-offset:-2px}.swagger-ui [type=search]::-webkit-search-cancel-button,.swagger-ui [type=search]::-webkit-search-decoration{-webkit-appearance:none}.swagger-ui ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.swagger-ui details,.swagger-ui menu{display:block}.swagger-ui summary{display:list-item}.swagger-ui canvas{display:inline-block}.swagger-ui template{display:none}.swagger-ui [hidden]{display:none}.swagger-ui .debug *{outline:1px solid gold}.swagger-ui .debug-white *{outline:1px solid #fff}.swagger-ui .debug-black *{outline:1px solid #000}.swagger-ui .debug-grid{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTRDOTY4N0U2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTRDOTY4N0Q2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3NjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3NzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsBS+GMAAAAjSURBVHjaYvz//z8DLsD4gcGXiYEAGBIKGBne//fFpwAgwAB98AaF2pjlUQAAAABJRU5ErkJggg==) repeat 0 0}.swagger-ui .debug-grid-16{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODYyRjhERDU2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODYyRjhERDQ2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QTY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3QjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvCS01IAAABMSURBVHjaYmR4/5+BFPBfAMFm/MBgx8RAGWCn1AAmSg34Q6kBDKMGMDCwICeMIemF/5QawEipAWwUhwEjMDvbAWlWkvVBwu8vQIABAEwBCph8U6c0AAAAAElFTkSuQmCC) repeat 0 0}.swagger-ui .debug-grid-8-solid{background:#fff url(data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAAAAAD/4QMxaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzExMSA3OS4xNTgzMjUsIDIwMTUvMDkvMTAtMDE6MTA6MjAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkIxMjI0OTczNjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkIxMjI0OTc0NjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QjEyMjQ5NzE2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QjEyMjQ5NzI2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAbGhopHSlBJiZBQi8vL0JHPz4+P0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHAR0pKTQmND8oKD9HPzU/R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0f/wAARCAAIAAgDASIAAhEBAxEB/8QAWQABAQAAAAAAAAAAAAAAAAAAAAYBAQEAAAAAAAAAAAAAAAAAAAIEEAEBAAMBAAAAAAAAAAAAAAABADECA0ERAAEDBQAAAAAAAAAAAAAAAAARITFBUWESIv/aAAwDAQACEQMRAD8AoOnTV1QTD7JJshP3vSM3P//Z) repeat 0 0}.swagger-ui .debug-grid-16-solid{background:#fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzY3MkJEN0U2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzY3MkJEN0Y2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3RDY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pve6J3kAAAAzSURBVHjaYvz//z8D0UDsMwMjSRoYP5Gq4SPNbRjVMEQ1fCRDg+in/6+J1AJUxsgAEGAA31BAJMS0GYEAAAAASUVORK5CYII=) repeat 0 0}.swagger-ui .border-box,.swagger-ui a,.swagger-ui article,.swagger-ui body,.swagger-ui code,.swagger-ui dd,.swagger-ui div,.swagger-ui dl,.swagger-ui dt,.swagger-ui fieldset,.swagger-ui footer,.swagger-ui form,.swagger-ui h1,.swagger-ui h2,.swagger-ui h3,.swagger-ui h4,.swagger-ui h5,.swagger-ui h6,.swagger-ui header,.swagger-ui html,.swagger-ui input[type=email],.swagger-ui input[type=number],.swagger-ui input[type=password],.swagger-ui input[type=tel],.swagger-ui input[type=text],.swagger-ui input[type=url],.swagger-ui legend,.swagger-ui li,.swagger-ui main,.swagger-ui ol,.swagger-ui p,.swagger-ui pre,.swagger-ui section,.swagger-ui table,.swagger-ui td,.swagger-ui textarea,.swagger-ui th,.swagger-ui tr,.swagger-ui ul{box-sizing:border-box}.swagger-ui .aspect-ratio{height:0;position:relative}.swagger-ui .aspect-ratio--16x9{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1{padding-bottom:100%}.swagger-ui .aspect-ratio--object{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}@media screen and (min-width:30em){.swagger-ui .aspect-ratio-ns{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-ns{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-ns{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-ns{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-ns{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-ns{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-ns{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-ns{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-ns{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-ns{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-ns{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-ns{padding-bottom:100%}.swagger-ui .aspect-ratio--object-ns{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .aspect-ratio-m{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-m{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-m{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-m{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-m{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-m{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-m{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-m{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-m{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-m{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-m{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-m{padding-bottom:100%}.swagger-ui .aspect-ratio--object-m{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}}@media screen and (min-width:60em){.swagger-ui .aspect-ratio-l{height:0;position:relative}.swagger-ui .aspect-ratio--16x9-l{padding-bottom:56.25%}.swagger-ui .aspect-ratio--9x16-l{padding-bottom:177.77%}.swagger-ui .aspect-ratio--4x3-l{padding-bottom:75%}.swagger-ui .aspect-ratio--3x4-l{padding-bottom:133.33%}.swagger-ui .aspect-ratio--6x4-l{padding-bottom:66.6%}.swagger-ui .aspect-ratio--4x6-l{padding-bottom:150%}.swagger-ui .aspect-ratio--8x5-l{padding-bottom:62.5%}.swagger-ui .aspect-ratio--5x8-l{padding-bottom:160%}.swagger-ui .aspect-ratio--7x5-l{padding-bottom:71.42%}.swagger-ui .aspect-ratio--5x7-l{padding-bottom:140%}.swagger-ui .aspect-ratio--1x1-l{padding-bottom:100%}.swagger-ui .aspect-ratio--object-l{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:100}}.swagger-ui img{max-width:100%}.swagger-ui .cover{background-size:cover!important}.swagger-ui .contain{background-size:contain!important}@media screen and (min-width:30em){.swagger-ui .cover-ns{background-size:cover!important}.swagger-ui .contain-ns{background-size:contain!important}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .cover-m{background-size:cover!important}.swagger-ui .contain-m{background-size:contain!important}}@media screen and (min-width:60em){.swagger-ui .cover-l{background-size:cover!important}.swagger-ui .contain-l{background-size:contain!important}}.swagger-ui .bg-center{background-repeat:no-repeat;background-position:50%}.swagger-ui .bg-top{background-repeat:no-repeat;background-position:top}.swagger-ui .bg-right{background-repeat:no-repeat;background-position:100%}.swagger-ui .bg-bottom{background-repeat:no-repeat;background-position:bottom}.swagger-ui .bg-left{background-repeat:no-repeat;background-position:0}@media screen and (min-width:30em){.swagger-ui .bg-center-ns{background-repeat:no-repeat;background-position:50%}.swagger-ui .bg-top-ns{background-repeat:no-repeat;background-position:top}.swagger-ui .bg-right-ns{background-repeat:no-repeat;background-position:100%}.swagger-ui .bg-bottom-ns{background-repeat:no-repeat;background-position:bottom}.swagger-ui .bg-left-ns{background-repeat:no-repeat;background-position:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .bg-center-m{background-repeat:no-repeat;background-position:50%}.swagger-ui .bg-top-m{background-repeat:no-repeat;background-position:top}.swagger-ui .bg-right-m{background-repeat:no-repeat;background-position:100%}.swagger-ui .bg-bottom-m{background-repeat:no-repeat;background-position:bottom}.swagger-ui .bg-left-m{background-repeat:no-repeat;background-position:0}}@media screen and (min-width:60em){.swagger-ui .bg-center-l{background-repeat:no-repeat;background-position:50%}.swagger-ui .bg-top-l{background-repeat:no-repeat;background-position:top}.swagger-ui .bg-right-l{background-repeat:no-repeat;background-position:100%}.swagger-ui .bg-bottom-l{background-repeat:no-repeat;background-position:bottom}.swagger-ui .bg-left-l{background-repeat:no-repeat;background-position:0}}.swagger-ui .outline{outline:1px solid}.swagger-ui .outline-transparent{outline:1px solid transparent}.swagger-ui .outline-0{outline:0}@media screen and (min-width:30em){.swagger-ui .outline-ns{outline:1px solid}.swagger-ui .outline-transparent-ns{outline:1px solid transparent}.swagger-ui .outline-0-ns{outline:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .outline-m{outline:1px solid}.swagger-ui .outline-transparent-m{outline:1px solid transparent}.swagger-ui .outline-0-m{outline:0}}@media screen and (min-width:60em){.swagger-ui .outline-l{outline:1px solid}.swagger-ui .outline-transparent-l{outline:1px solid transparent}.swagger-ui .outline-0-l{outline:0}}.swagger-ui .ba{border-style:solid;border-width:1px}.swagger-ui .bt{border-top-style:solid;border-top-width:1px}.swagger-ui .br{border-right-style:solid;border-right-width:1px}.swagger-ui .bb{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl{border-left-style:solid;border-left-width:1px}.swagger-ui .bn{border-style:none;border-width:0}@media screen and (min-width:30em){.swagger-ui .ba-ns{border-style:solid;border-width:1px}.swagger-ui .bt-ns{border-top-style:solid;border-top-width:1px}.swagger-ui .br-ns{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-ns{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-ns{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-ns{border-style:none;border-width:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .ba-m{border-style:solid;border-width:1px}.swagger-ui .bt-m{border-top-style:solid;border-top-width:1px}.swagger-ui .br-m{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-m{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-m{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-m{border-style:none;border-width:0}}@media screen and (min-width:60em){.swagger-ui .ba-l{border-style:solid;border-width:1px}.swagger-ui .bt-l{border-top-style:solid;border-top-width:1px}.swagger-ui .br-l{border-right-style:solid;border-right-width:1px}.swagger-ui .bb-l{border-bottom-style:solid;border-bottom-width:1px}.swagger-ui .bl-l{border-left-style:solid;border-left-width:1px}.swagger-ui .bn-l{border-style:none;border-width:0}}.swagger-ui .b--black{border-color:#000}.swagger-ui .b--near-black{border-color:#111}.swagger-ui .b--dark-gray{border-color:#333}.swagger-ui .b--mid-gray{border-color:#555}.swagger-ui .b--gray{border-color:#777}.swagger-ui .b--silver{border-color:#999}.swagger-ui .b--light-silver{border-color:#aaa}.swagger-ui .b--moon-gray{border-color:#ccc}.swagger-ui .b--light-gray{border-color:#eee}.swagger-ui .b--near-white{border-color:#f4f4f4}.swagger-ui .b--white{border-color:#fff}.swagger-ui .b--white-90{border-color:hsla(0,0%,100%,.9)}.swagger-ui .b--white-80{border-color:hsla(0,0%,100%,.8)}.swagger-ui .b--white-70{border-color:hsla(0,0%,100%,.7)}.swagger-ui .b--white-60{border-color:hsla(0,0%,100%,.6)}.swagger-ui .b--white-50{border-color:hsla(0,0%,100%,.5)}.swagger-ui .b--white-40{border-color:hsla(0,0%,100%,.4)}.swagger-ui .b--white-30{border-color:hsla(0,0%,100%,.3)}.swagger-ui .b--white-20{border-color:hsla(0,0%,100%,.2)}.swagger-ui .b--white-10{border-color:hsla(0,0%,100%,.1)}.swagger-ui .b--white-05{border-color:hsla(0,0%,100%,.05)}.swagger-ui .b--white-025{border-color:hsla(0,0%,100%,.025)}.swagger-ui .b--white-0125{border-color:hsla(0,0%,100%,.0125)}.swagger-ui .b--black-90{border-color:rgba(0,0,0,.9)}.swagger-ui .b--black-80{border-color:rgba(0,0,0,.8)}.swagger-ui .b--black-70{border-color:rgba(0,0,0,.7)}.swagger-ui .b--black-60{border-color:rgba(0,0,0,.6)}.swagger-ui .b--black-50{border-color:rgba(0,0,0,.5)}.swagger-ui .b--black-40{border-color:rgba(0,0,0,.4)}.swagger-ui .b--black-30{border-color:rgba(0,0,0,.3)}.swagger-ui .b--black-20{border-color:rgba(0,0,0,.2)}.swagger-ui .b--black-10{border-color:rgba(0,0,0,.1)}.swagger-ui .b--black-05{border-color:rgba(0,0,0,.05)}.swagger-ui .b--black-025{border-color:rgba(0,0,0,.025)}.swagger-ui .b--black-0125{border-color:rgba(0,0,0,.0125)}.swagger-ui .b--dark-red{border-color:#e7040f}.swagger-ui .b--red{border-color:#ff4136}.swagger-ui .b--light-red{border-color:#ff725c}.swagger-ui .b--orange{border-color:#ff6300}.swagger-ui .b--gold{border-color:#ffb700}.swagger-ui .b--yellow{border-color:gold}.swagger-ui .b--light-yellow{border-color:#fbf1a9}.swagger-ui .b--purple{border-color:#5e2ca5}.swagger-ui .b--light-purple{border-color:#a463f2}.swagger-ui .b--dark-pink{border-color:#d5008f}.swagger-ui .b--hot-pink{border-color:#ff41b4}.swagger-ui .b--pink{border-color:#ff80cc}.swagger-ui .b--light-pink{border-color:#ffa3d7}.swagger-ui .b--dark-green{border-color:#137752}.swagger-ui .b--green{border-color:#19a974}.swagger-ui .b--light-green{border-color:#9eebcf}.swagger-ui .b--navy{border-color:#001b44}.swagger-ui .b--dark-blue{border-color:#00449e}.swagger-ui .b--blue{border-color:#357edd}.swagger-ui .b--light-blue{border-color:#96ccff}.swagger-ui .b--lightest-blue{border-color:#cdecff}.swagger-ui .b--washed-blue{border-color:#f6fffe}.swagger-ui .b--washed-green{border-color:#e8fdf5}.swagger-ui .b--washed-yellow{border-color:#fffceb}.swagger-ui .b--washed-red{border-color:#ffdfdf}.swagger-ui .b--transparent{border-color:transparent}.swagger-ui .b--inherit{border-color:inherit}.swagger-ui .br0{border-radius:0}.swagger-ui .br1{border-radius:.125rem}.swagger-ui .br2{border-radius:.25rem}.swagger-ui .br3{border-radius:.5rem}.swagger-ui .br4{border-radius:1rem}.swagger-ui .br-100{border-radius:100%}.swagger-ui .br-pill{border-radius:9999px}.swagger-ui .br--bottom{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right{border-top-left-radius:0;border-bottom-left-radius:0}.swagger-ui .br--left{border-top-right-radius:0;border-bottom-right-radius:0}@media screen and (min-width:30em){.swagger-ui .br0-ns{border-radius:0}.swagger-ui .br1-ns{border-radius:.125rem}.swagger-ui .br2-ns{border-radius:.25rem}.swagger-ui .br3-ns{border-radius:.5rem}.swagger-ui .br4-ns{border-radius:1rem}.swagger-ui .br-100-ns{border-radius:100%}.swagger-ui .br-pill-ns{border-radius:9999px}.swagger-ui .br--bottom-ns{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-ns{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-ns{border-top-left-radius:0;border-bottom-left-radius:0}.swagger-ui .br--left-ns{border-top-right-radius:0;border-bottom-right-radius:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .br0-m{border-radius:0}.swagger-ui .br1-m{border-radius:.125rem}.swagger-ui .br2-m{border-radius:.25rem}.swagger-ui .br3-m{border-radius:.5rem}.swagger-ui .br4-m{border-radius:1rem}.swagger-ui .br-100-m{border-radius:100%}.swagger-ui .br-pill-m{border-radius:9999px}.swagger-ui .br--bottom-m{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-m{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-m{border-top-left-radius:0;border-bottom-left-radius:0}.swagger-ui .br--left-m{border-top-right-radius:0;border-bottom-right-radius:0}}@media screen and (min-width:60em){.swagger-ui .br0-l{border-radius:0}.swagger-ui .br1-l{border-radius:.125rem}.swagger-ui .br2-l{border-radius:.25rem}.swagger-ui .br3-l{border-radius:.5rem}.swagger-ui .br4-l{border-radius:1rem}.swagger-ui .br-100-l{border-radius:100%}.swagger-ui .br-pill-l{border-radius:9999px}.swagger-ui .br--bottom-l{border-top-left-radius:0;border-top-right-radius:0}.swagger-ui .br--top-l{border-bottom-left-radius:0;border-bottom-right-radius:0}.swagger-ui .br--right-l{border-top-left-radius:0;border-bottom-left-radius:0}.swagger-ui .br--left-l{border-top-right-radius:0;border-bottom-right-radius:0}}.swagger-ui .b--dotted{border-style:dotted}.swagger-ui .b--dashed{border-style:dashed}.swagger-ui .b--solid{border-style:solid}.swagger-ui .b--none{border-style:none}@media screen and (min-width:30em){.swagger-ui .b--dotted-ns{border-style:dotted}.swagger-ui .b--dashed-ns{border-style:dashed}.swagger-ui .b--solid-ns{border-style:solid}.swagger-ui .b--none-ns{border-style:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .b--dotted-m{border-style:dotted}.swagger-ui .b--dashed-m{border-style:dashed}.swagger-ui .b--solid-m{border-style:solid}.swagger-ui .b--none-m{border-style:none}}@media screen and (min-width:60em){.swagger-ui .b--dotted-l{border-style:dotted}.swagger-ui .b--dashed-l{border-style:dashed}.swagger-ui .b--solid-l{border-style:solid}.swagger-ui .b--none-l{border-style:none}}.swagger-ui .bw0{border-width:0}.swagger-ui .bw1{border-width:.125rem}.swagger-ui .bw2{border-width:.25rem}.swagger-ui .bw3{border-width:.5rem}.swagger-ui .bw4{border-width:1rem}.swagger-ui .bw5{border-width:2rem}.swagger-ui .bt-0{border-top-width:0}.swagger-ui .br-0{border-right-width:0}.swagger-ui .bb-0{border-bottom-width:0}.swagger-ui .bl-0{border-left-width:0}@media screen and (min-width:30em){.swagger-ui .bw0-ns{border-width:0}.swagger-ui .bw1-ns{border-width:.125rem}.swagger-ui .bw2-ns{border-width:.25rem}.swagger-ui .bw3-ns{border-width:.5rem}.swagger-ui .bw4-ns{border-width:1rem}.swagger-ui .bw5-ns{border-width:2rem}.swagger-ui .bt-0-ns{border-top-width:0}.swagger-ui .br-0-ns{border-right-width:0}.swagger-ui .bb-0-ns{border-bottom-width:0}.swagger-ui .bl-0-ns{border-left-width:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .bw0-m{border-width:0}.swagger-ui .bw1-m{border-width:.125rem}.swagger-ui .bw2-m{border-width:.25rem}.swagger-ui .bw3-m{border-width:.5rem}.swagger-ui .bw4-m{border-width:1rem}.swagger-ui .bw5-m{border-width:2rem}.swagger-ui .bt-0-m{border-top-width:0}.swagger-ui .br-0-m{border-right-width:0}.swagger-ui .bb-0-m{border-bottom-width:0}.swagger-ui .bl-0-m{border-left-width:0}}@media screen and (min-width:60em){.swagger-ui .bw0-l{border-width:0}.swagger-ui .bw1-l{border-width:.125rem}.swagger-ui .bw2-l{border-width:.25rem}.swagger-ui .bw3-l{border-width:.5rem}.swagger-ui .bw4-l{border-width:1rem}.swagger-ui .bw5-l{border-width:2rem}.swagger-ui .bt-0-l{border-top-width:0}.swagger-ui .br-0-l{border-right-width:0}.swagger-ui .bb-0-l{border-bottom-width:0}.swagger-ui .bl-0-l{border-left-width:0}}.swagger-ui .shadow-1{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}@media screen and (min-width:30em){.swagger-ui .shadow-1-ns{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2-ns{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3-ns{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4-ns{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5-ns{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .shadow-1-m{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2-m{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3-m{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4-m{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5-m{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}@media screen and (min-width:60em){.swagger-ui .shadow-1-l{box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-2-l{box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-3-l{box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.swagger-ui .shadow-4-l{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.swagger-ui .shadow-5-l{box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}.swagger-ui .pre{overflow-x:auto;overflow-y:hidden;overflow:scroll}.swagger-ui .top-0{top:0}.swagger-ui .right-0{right:0}.swagger-ui .bottom-0{bottom:0}.swagger-ui .left-0{left:0}.swagger-ui .top-1{top:1rem}.swagger-ui .right-1{right:1rem}.swagger-ui .bottom-1{bottom:1rem}.swagger-ui .left-1{left:1rem}.swagger-ui .top-2{top:2rem}.swagger-ui .right-2{right:2rem}.swagger-ui .bottom-2{bottom:2rem}.swagger-ui .left-2{left:2rem}.swagger-ui .top--1{top:-1rem}.swagger-ui .right--1{right:-1rem}.swagger-ui .bottom--1{bottom:-1rem}.swagger-ui .left--1{left:-1rem}.swagger-ui .top--2{top:-2rem}.swagger-ui .right--2{right:-2rem}.swagger-ui .bottom--2{bottom:-2rem}.swagger-ui .left--2{left:-2rem}.swagger-ui .absolute--fill{top:0;right:0;bottom:0;left:0}@media screen and (min-width:30em){.swagger-ui .top-0-ns{top:0}.swagger-ui .left-0-ns{left:0}.swagger-ui .right-0-ns{right:0}.swagger-ui .bottom-0-ns{bottom:0}.swagger-ui .top-1-ns{top:1rem}.swagger-ui .left-1-ns{left:1rem}.swagger-ui .right-1-ns{right:1rem}.swagger-ui .bottom-1-ns{bottom:1rem}.swagger-ui .top-2-ns{top:2rem}.swagger-ui .left-2-ns{left:2rem}.swagger-ui .right-2-ns{right:2rem}.swagger-ui .bottom-2-ns{bottom:2rem}.swagger-ui .top--1-ns{top:-1rem}.swagger-ui .right--1-ns{right:-1rem}.swagger-ui .bottom--1-ns{bottom:-1rem}.swagger-ui .left--1-ns{left:-1rem}.swagger-ui .top--2-ns{top:-2rem}.swagger-ui .right--2-ns{right:-2rem}.swagger-ui .bottom--2-ns{bottom:-2rem}.swagger-ui .left--2-ns{left:-2rem}.swagger-ui .absolute--fill-ns{top:0;right:0;bottom:0;left:0}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .top-0-m{top:0}.swagger-ui .left-0-m{left:0}.swagger-ui .right-0-m{right:0}.swagger-ui .bottom-0-m{bottom:0}.swagger-ui .top-1-m{top:1rem}.swagger-ui .left-1-m{left:1rem}.swagger-ui .right-1-m{right:1rem}.swagger-ui .bottom-1-m{bottom:1rem}.swagger-ui .top-2-m{top:2rem}.swagger-ui .left-2-m{left:2rem}.swagger-ui .right-2-m{right:2rem}.swagger-ui .bottom-2-m{bottom:2rem}.swagger-ui .top--1-m{top:-1rem}.swagger-ui .right--1-m{right:-1rem}.swagger-ui .bottom--1-m{bottom:-1rem}.swagger-ui .left--1-m{left:-1rem}.swagger-ui .top--2-m{top:-2rem}.swagger-ui .right--2-m{right:-2rem}.swagger-ui .bottom--2-m{bottom:-2rem}.swagger-ui .left--2-m{left:-2rem}.swagger-ui .absolute--fill-m{top:0;right:0;bottom:0;left:0}}@media screen and (min-width:60em){.swagger-ui .top-0-l{top:0}.swagger-ui .left-0-l{left:0}.swagger-ui .right-0-l{right:0}.swagger-ui .bottom-0-l{bottom:0}.swagger-ui .top-1-l{top:1rem}.swagger-ui .left-1-l{left:1rem}.swagger-ui .right-1-l{right:1rem}.swagger-ui .bottom-1-l{bottom:1rem}.swagger-ui .top-2-l{top:2rem}.swagger-ui .left-2-l{left:2rem}.swagger-ui .right-2-l{right:2rem}.swagger-ui .bottom-2-l{bottom:2rem}.swagger-ui .top--1-l{top:-1rem}.swagger-ui .right--1-l{right:-1rem}.swagger-ui .bottom--1-l{bottom:-1rem}.swagger-ui .left--1-l{left:-1rem}.swagger-ui .top--2-l{top:-2rem}.swagger-ui .right--2-l{right:-2rem}.swagger-ui .bottom--2-l{bottom:-2rem}.swagger-ui .left--2-l{left:-2rem}.swagger-ui .absolute--fill-l{top:0;right:0;bottom:0;left:0}}.swagger-ui .cf:after,.swagger-ui .cf:before{content:" ";display:table}.swagger-ui .cf:after{clear:both}.swagger-ui .cf{*zoom:1}.swagger-ui .cl{clear:left}.swagger-ui .cr{clear:right}.swagger-ui .cb{clear:both}.swagger-ui .cn{clear:none}@media screen and (min-width:30em){.swagger-ui .cl-ns{clear:left}.swagger-ui .cr-ns{clear:right}.swagger-ui .cb-ns{clear:both}.swagger-ui .cn-ns{clear:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .cl-m{clear:left}.swagger-ui .cr-m{clear:right}.swagger-ui .cb-m{clear:both}.swagger-ui .cn-m{clear:none}}@media screen and (min-width:60em){.swagger-ui .cl-l{clear:left}.swagger-ui .cr-l{clear:right}.swagger-ui .cb-l{clear:both}.swagger-ui .cn-l{clear:none}}.swagger-ui .flex{display:flex}.swagger-ui .inline-flex{display:inline-flex}.swagger-ui .flex-auto{flex:1 1 auto;min-width:0;min-height:0}.swagger-ui .flex-none{flex:none}.swagger-ui .flex-column{flex-direction:column}.swagger-ui .flex-row{flex-direction:row}.swagger-ui .flex-wrap{flex-wrap:wrap}.swagger-ui .flex-nowrap{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse{flex-direction:column-reverse}.swagger-ui .flex-row-reverse{flex-direction:row-reverse}.swagger-ui .items-start{align-items:flex-start}.swagger-ui .items-end{align-items:flex-end}.swagger-ui .items-center{align-items:center}.swagger-ui .items-baseline{align-items:baseline}.swagger-ui .items-stretch{align-items:stretch}.swagger-ui .self-start{align-self:flex-start}.swagger-ui .self-end{align-self:flex-end}.swagger-ui .self-center{align-self:center}.swagger-ui .self-baseline{align-self:baseline}.swagger-ui .self-stretch{align-self:stretch}.swagger-ui .justify-start{justify-content:flex-start}.swagger-ui .justify-end{justify-content:flex-end}.swagger-ui .justify-center{justify-content:center}.swagger-ui .justify-between{justify-content:space-between}.swagger-ui .justify-around{justify-content:space-around}.swagger-ui .content-start{align-content:flex-start}.swagger-ui .content-end{align-content:flex-end}.swagger-ui .content-center{align-content:center}.swagger-ui .content-between{align-content:space-between}.swagger-ui .content-around{align-content:space-around}.swagger-ui .content-stretch{align-content:stretch}.swagger-ui .order-0{order:0}.swagger-ui .order-1{order:1}.swagger-ui .order-2{order:2}.swagger-ui .order-3{order:3}.swagger-ui .order-4{order:4}.swagger-ui .order-5{order:5}.swagger-ui .order-6{order:6}.swagger-ui .order-7{order:7}.swagger-ui .order-8{order:8}.swagger-ui .order-last{order:99999}.swagger-ui .flex-grow-0{flex-grow:0}.swagger-ui .flex-grow-1{flex-grow:1}.swagger-ui .flex-shrink-0{flex-shrink:0}.swagger-ui .flex-shrink-1{flex-shrink:1}@media screen and (min-width:30em){.swagger-ui .flex-ns{display:flex}.swagger-ui .inline-flex-ns{display:inline-flex}.swagger-ui .flex-auto-ns{flex:1 1 auto;min-width:0;min-height:0}.swagger-ui .flex-none-ns{flex:none}.swagger-ui .flex-column-ns{flex-direction:column}.swagger-ui .flex-row-ns{flex-direction:row}.swagger-ui .flex-wrap-ns{flex-wrap:wrap}.swagger-ui .flex-nowrap-ns{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-ns{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-ns{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-ns{flex-direction:row-reverse}.swagger-ui .items-start-ns{align-items:flex-start}.swagger-ui .items-end-ns{align-items:flex-end}.swagger-ui .items-center-ns{align-items:center}.swagger-ui .items-baseline-ns{align-items:baseline}.swagger-ui .items-stretch-ns{align-items:stretch}.swagger-ui .self-start-ns{align-self:flex-start}.swagger-ui .self-end-ns{align-self:flex-end}.swagger-ui .self-center-ns{align-self:center}.swagger-ui .self-baseline-ns{align-self:baseline}.swagger-ui .self-stretch-ns{align-self:stretch}.swagger-ui .justify-start-ns{justify-content:flex-start}.swagger-ui .justify-end-ns{justify-content:flex-end}.swagger-ui .justify-center-ns{justify-content:center}.swagger-ui .justify-between-ns{justify-content:space-between}.swagger-ui .justify-around-ns{justify-content:space-around}.swagger-ui .content-start-ns{align-content:flex-start}.swagger-ui .content-end-ns{align-content:flex-end}.swagger-ui .content-center-ns{align-content:center}.swagger-ui .content-between-ns{align-content:space-between}.swagger-ui .content-around-ns{align-content:space-around}.swagger-ui .content-stretch-ns{align-content:stretch}.swagger-ui .order-0-ns{order:0}.swagger-ui .order-1-ns{order:1}.swagger-ui .order-2-ns{order:2}.swagger-ui .order-3-ns{order:3}.swagger-ui .order-4-ns{order:4}.swagger-ui .order-5-ns{order:5}.swagger-ui .order-6-ns{order:6}.swagger-ui .order-7-ns{order:7}.swagger-ui .order-8-ns{order:8}.swagger-ui .order-last-ns{order:99999}.swagger-ui .flex-grow-0-ns{flex-grow:0}.swagger-ui .flex-grow-1-ns{flex-grow:1}.swagger-ui .flex-shrink-0-ns{flex-shrink:0}.swagger-ui .flex-shrink-1-ns{flex-shrink:1}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .flex-m{display:flex}.swagger-ui .inline-flex-m{display:inline-flex}.swagger-ui .flex-auto-m{flex:1 1 auto;min-width:0;min-height:0}.swagger-ui .flex-none-m{flex:none}.swagger-ui .flex-column-m{flex-direction:column}.swagger-ui .flex-row-m{flex-direction:row}.swagger-ui .flex-wrap-m{flex-wrap:wrap}.swagger-ui .flex-nowrap-m{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-m{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-m{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-m{flex-direction:row-reverse}.swagger-ui .items-start-m{align-items:flex-start}.swagger-ui .items-end-m{align-items:flex-end}.swagger-ui .items-center-m{align-items:center}.swagger-ui .items-baseline-m{align-items:baseline}.swagger-ui .items-stretch-m{align-items:stretch}.swagger-ui .self-start-m{align-self:flex-start}.swagger-ui .self-end-m{align-self:flex-end}.swagger-ui .self-center-m{align-self:center}.swagger-ui .self-baseline-m{align-self:baseline}.swagger-ui .self-stretch-m{align-self:stretch}.swagger-ui .justify-start-m{justify-content:flex-start}.swagger-ui .justify-end-m{justify-content:flex-end}.swagger-ui .justify-center-m{justify-content:center}.swagger-ui .justify-between-m{justify-content:space-between}.swagger-ui .justify-around-m{justify-content:space-around}.swagger-ui .content-start-m{align-content:flex-start}.swagger-ui .content-end-m{align-content:flex-end}.swagger-ui .content-center-m{align-content:center}.swagger-ui .content-between-m{align-content:space-between}.swagger-ui .content-around-m{align-content:space-around}.swagger-ui .content-stretch-m{align-content:stretch}.swagger-ui .order-0-m{order:0}.swagger-ui .order-1-m{order:1}.swagger-ui .order-2-m{order:2}.swagger-ui .order-3-m{order:3}.swagger-ui .order-4-m{order:4}.swagger-ui .order-5-m{order:5}.swagger-ui .order-6-m{order:6}.swagger-ui .order-7-m{order:7}.swagger-ui .order-8-m{order:8}.swagger-ui .order-last-m{order:99999}.swagger-ui .flex-grow-0-m{flex-grow:0}.swagger-ui .flex-grow-1-m{flex-grow:1}.swagger-ui .flex-shrink-0-m{flex-shrink:0}.swagger-ui .flex-shrink-1-m{flex-shrink:1}}@media screen and (min-width:60em){.swagger-ui .flex-l{display:flex}.swagger-ui .inline-flex-l{display:inline-flex}.swagger-ui .flex-auto-l{flex:1 1 auto;min-width:0;min-height:0}.swagger-ui .flex-none-l{flex:none}.swagger-ui .flex-column-l{flex-direction:column}.swagger-ui .flex-row-l{flex-direction:row}.swagger-ui .flex-wrap-l{flex-wrap:wrap}.swagger-ui .flex-nowrap-l{flex-wrap:nowrap}.swagger-ui .flex-wrap-reverse-l{flex-wrap:wrap-reverse}.swagger-ui .flex-column-reverse-l{flex-direction:column-reverse}.swagger-ui .flex-row-reverse-l{flex-direction:row-reverse}.swagger-ui .items-start-l{align-items:flex-start}.swagger-ui .items-end-l{align-items:flex-end}.swagger-ui .items-center-l{align-items:center}.swagger-ui .items-baseline-l{align-items:baseline}.swagger-ui .items-stretch-l{align-items:stretch}.swagger-ui .self-start-l{align-self:flex-start}.swagger-ui .self-end-l{align-self:flex-end}.swagger-ui .self-center-l{align-self:center}.swagger-ui .self-baseline-l{align-self:baseline}.swagger-ui .self-stretch-l{align-self:stretch}.swagger-ui .justify-start-l{justify-content:flex-start}.swagger-ui .justify-end-l{justify-content:flex-end}.swagger-ui .justify-center-l{justify-content:center}.swagger-ui .justify-between-l{justify-content:space-between}.swagger-ui .justify-around-l{justify-content:space-around}.swagger-ui .content-start-l{align-content:flex-start}.swagger-ui .content-end-l{align-content:flex-end}.swagger-ui .content-center-l{align-content:center}.swagger-ui .content-between-l{align-content:space-between}.swagger-ui .content-around-l{align-content:space-around}.swagger-ui .content-stretch-l{align-content:stretch}.swagger-ui .order-0-l{order:0}.swagger-ui .order-1-l{order:1}.swagger-ui .order-2-l{order:2}.swagger-ui .order-3-l{order:3}.swagger-ui .order-4-l{order:4}.swagger-ui .order-5-l{order:5}.swagger-ui .order-6-l{order:6}.swagger-ui .order-7-l{order:7}.swagger-ui .order-8-l{order:8}.swagger-ui .order-last-l{order:99999}.swagger-ui .flex-grow-0-l{flex-grow:0}.swagger-ui .flex-grow-1-l{flex-grow:1}.swagger-ui .flex-shrink-0-l{flex-shrink:0}.swagger-ui .flex-shrink-1-l{flex-shrink:1}}.swagger-ui .dn{display:none}.swagger-ui .di{display:inline}.swagger-ui .db{display:block}.swagger-ui .dib{display:inline-block}.swagger-ui .dit{display:inline-table}.swagger-ui .dt{display:table}.swagger-ui .dtc{display:table-cell}.swagger-ui .dt-row{display:table-row}.swagger-ui .dt-row-group{display:table-row-group}.swagger-ui .dt-column{display:table-column}.swagger-ui .dt-column-group{display:table-column-group}.swagger-ui .dt--fixed{table-layout:fixed;width:100%}@media screen and (min-width:30em){.swagger-ui .dn-ns{display:none}.swagger-ui .di-ns{display:inline}.swagger-ui .db-ns{display:block}.swagger-ui .dib-ns{display:inline-block}.swagger-ui .dit-ns{display:inline-table}.swagger-ui .dt-ns{display:table}.swagger-ui .dtc-ns{display:table-cell}.swagger-ui .dt-row-ns{display:table-row}.swagger-ui .dt-row-group-ns{display:table-row-group}.swagger-ui .dt-column-ns{display:table-column}.swagger-ui .dt-column-group-ns{display:table-column-group}.swagger-ui .dt--fixed-ns{table-layout:fixed;width:100%}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .dn-m{display:none}.swagger-ui .di-m{display:inline}.swagger-ui .db-m{display:block}.swagger-ui .dib-m{display:inline-block}.swagger-ui .dit-m{display:inline-table}.swagger-ui .dt-m{display:table}.swagger-ui .dtc-m{display:table-cell}.swagger-ui .dt-row-m{display:table-row}.swagger-ui .dt-row-group-m{display:table-row-group}.swagger-ui .dt-column-m{display:table-column}.swagger-ui .dt-column-group-m{display:table-column-group}.swagger-ui .dt--fixed-m{table-layout:fixed;width:100%}}@media screen and (min-width:60em){.swagger-ui .dn-l{display:none}.swagger-ui .di-l{display:inline}.swagger-ui .db-l{display:block}.swagger-ui .dib-l{display:inline-block}.swagger-ui .dit-l{display:inline-table}.swagger-ui .dt-l{display:table}.swagger-ui .dtc-l{display:table-cell}.swagger-ui .dt-row-l{display:table-row}.swagger-ui .dt-row-group-l{display:table-row-group}.swagger-ui .dt-column-l{display:table-column}.swagger-ui .dt-column-group-l{display:table-column-group}.swagger-ui .dt--fixed-l{table-layout:fixed;width:100%}}.swagger-ui .fl{float:left;_display:inline}.swagger-ui .fr{float:right;_display:inline}.swagger-ui .fn{float:none}@media screen and (min-width:30em){.swagger-ui .fl-ns{float:left;_display:inline}.swagger-ui .fr-ns{float:right;_display:inline}.swagger-ui .fn-ns{float:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .fl-m{float:left;_display:inline}.swagger-ui .fr-m{float:right;_display:inline}.swagger-ui .fn-m{float:none}}@media screen and (min-width:60em){.swagger-ui .fl-l{float:left;_display:inline}.swagger-ui .fr-l{float:right;_display:inline}.swagger-ui .fn-l{float:none}}.swagger-ui .sans-serif{font-family:-apple-system,BlinkMacSystemFont,avenir next,avenir,helvetica,helvetica neue,ubuntu,roboto,noto,segoe ui,arial,sans-serif}.swagger-ui .serif{font-family:georgia,serif}.swagger-ui .system-sans-serif{font-family:sans-serif}.swagger-ui .system-serif{font-family:serif}.swagger-ui .code,.swagger-ui code{font-family:Consolas,monaco,monospace}.swagger-ui .courier{font-family:Courier Next,courier,monospace}.swagger-ui .helvetica{font-family:helvetica neue,helvetica,sans-serif}.swagger-ui .avenir{font-family:avenir next,avenir,sans-serif}.swagger-ui .athelas{font-family:athelas,georgia,serif}.swagger-ui .georgia{font-family:georgia,serif}.swagger-ui .times{font-family:times,serif}.swagger-ui .bodoni{font-family:Bodoni MT,serif}.swagger-ui .calisto{font-family:Calisto MT,serif}.swagger-ui .garamond{font-family:garamond,serif}.swagger-ui .baskerville{font-family:baskerville,serif}.swagger-ui .i{font-style:italic}.swagger-ui .fs-normal{font-style:normal}@media screen and (min-width:30em){.swagger-ui .i-ns{font-style:italic}.swagger-ui .fs-normal-ns{font-style:normal}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .i-m{font-style:italic}.swagger-ui .fs-normal-m{font-style:normal}}@media screen and (min-width:60em){.swagger-ui .i-l{font-style:italic}.swagger-ui .fs-normal-l{font-style:normal}}.swagger-ui .normal{font-weight:400}.swagger-ui .b{font-weight:700}.swagger-ui .fw1{font-weight:100}.swagger-ui .fw2{font-weight:200}.swagger-ui .fw3{font-weight:300}.swagger-ui .fw4{font-weight:400}.swagger-ui .fw5{font-weight:500}.swagger-ui .fw6{font-weight:600}.swagger-ui .fw7{font-weight:700}.swagger-ui .fw8{font-weight:800}.swagger-ui .fw9{font-weight:900}@media screen and (min-width:30em){.swagger-ui .normal-ns{font-weight:400}.swagger-ui .b-ns{font-weight:700}.swagger-ui .fw1-ns{font-weight:100}.swagger-ui .fw2-ns{font-weight:200}.swagger-ui .fw3-ns{font-weight:300}.swagger-ui .fw4-ns{font-weight:400}.swagger-ui .fw5-ns{font-weight:500}.swagger-ui .fw6-ns{font-weight:600}.swagger-ui .fw7-ns{font-weight:700}.swagger-ui .fw8-ns{font-weight:800}.swagger-ui .fw9-ns{font-weight:900}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .normal-m{font-weight:400}.swagger-ui .b-m{font-weight:700}.swagger-ui .fw1-m{font-weight:100}.swagger-ui .fw2-m{font-weight:200}.swagger-ui .fw3-m{font-weight:300}.swagger-ui .fw4-m{font-weight:400}.swagger-ui .fw5-m{font-weight:500}.swagger-ui .fw6-m{font-weight:600}.swagger-ui .fw7-m{font-weight:700}.swagger-ui .fw8-m{font-weight:800}.swagger-ui .fw9-m{font-weight:900}}@media screen and (min-width:60em){.swagger-ui .normal-l{font-weight:400}.swagger-ui .b-l{font-weight:700}.swagger-ui .fw1-l{font-weight:100}.swagger-ui .fw2-l{font-weight:200}.swagger-ui .fw3-l{font-weight:300}.swagger-ui .fw4-l{font-weight:400}.swagger-ui .fw5-l{font-weight:500}.swagger-ui .fw6-l{font-weight:600}.swagger-ui .fw7-l{font-weight:700}.swagger-ui .fw8-l{font-weight:800}.swagger-ui .fw9-l{font-weight:900}}.swagger-ui .input-reset{-webkit-appearance:none;-moz-appearance:none}.swagger-ui .button-reset::-moz-focus-inner,.swagger-ui .input-reset::-moz-focus-inner{border:0;padding:0}.swagger-ui .h1{height:1rem}.swagger-ui .h2{height:2rem}.swagger-ui .h3{height:4rem}.swagger-ui .h4{height:8rem}.swagger-ui .h5{height:16rem}.swagger-ui .h-25{height:25%}.swagger-ui .h-50{height:50%}.swagger-ui .h-75{height:75%}.swagger-ui .h-100{height:100%}.swagger-ui .min-h-100{min-height:100%}.swagger-ui .vh-25{height:25vh}.swagger-ui .vh-50{height:50vh}.swagger-ui .vh-75{height:75vh}.swagger-ui .vh-100{height:100vh}.swagger-ui .min-vh-100{min-height:100vh}.swagger-ui .h-auto{height:auto}.swagger-ui .h-inherit{height:inherit}@media screen and (min-width:30em){.swagger-ui .h1-ns{height:1rem}.swagger-ui .h2-ns{height:2rem}.swagger-ui .h3-ns{height:4rem}.swagger-ui .h4-ns{height:8rem}.swagger-ui .h5-ns{height:16rem}.swagger-ui .h-25-ns{height:25%}.swagger-ui .h-50-ns{height:50%}.swagger-ui .h-75-ns{height:75%}.swagger-ui .h-100-ns{height:100%}.swagger-ui .min-h-100-ns{min-height:100%}.swagger-ui .vh-25-ns{height:25vh}.swagger-ui .vh-50-ns{height:50vh}.swagger-ui .vh-75-ns{height:75vh}.swagger-ui .vh-100-ns{height:100vh}.swagger-ui .min-vh-100-ns{min-height:100vh}.swagger-ui .h-auto-ns{height:auto}.swagger-ui .h-inherit-ns{height:inherit}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .h1-m{height:1rem}.swagger-ui .h2-m{height:2rem}.swagger-ui .h3-m{height:4rem}.swagger-ui .h4-m{height:8rem}.swagger-ui .h5-m{height:16rem}.swagger-ui .h-25-m{height:25%}.swagger-ui .h-50-m{height:50%}.swagger-ui .h-75-m{height:75%}.swagger-ui .h-100-m{height:100%}.swagger-ui .min-h-100-m{min-height:100%}.swagger-ui .vh-25-m{height:25vh}.swagger-ui .vh-50-m{height:50vh}.swagger-ui .vh-75-m{height:75vh}.swagger-ui .vh-100-m{height:100vh}.swagger-ui .min-vh-100-m{min-height:100vh}.swagger-ui .h-auto-m{height:auto}.swagger-ui .h-inherit-m{height:inherit}}@media screen and (min-width:60em){.swagger-ui .h1-l{height:1rem}.swagger-ui .h2-l{height:2rem}.swagger-ui .h3-l{height:4rem}.swagger-ui .h4-l{height:8rem}.swagger-ui .h5-l{height:16rem}.swagger-ui .h-25-l{height:25%}.swagger-ui .h-50-l{height:50%}.swagger-ui .h-75-l{height:75%}.swagger-ui .h-100-l{height:100%}.swagger-ui .min-h-100-l{min-height:100%}.swagger-ui .vh-25-l{height:25vh}.swagger-ui .vh-50-l{height:50vh}.swagger-ui .vh-75-l{height:75vh}.swagger-ui .vh-100-l{height:100vh}.swagger-ui .min-vh-100-l{min-height:100vh}.swagger-ui .h-auto-l{height:auto}.swagger-ui .h-inherit-l{height:inherit}}.swagger-ui .tracked{letter-spacing:.1em}.swagger-ui .tracked-tight{letter-spacing:-.05em}.swagger-ui .tracked-mega{letter-spacing:.25em}@media screen and (min-width:30em){.swagger-ui .tracked-ns{letter-spacing:.1em}.swagger-ui .tracked-tight-ns{letter-spacing:-.05em}.swagger-ui .tracked-mega-ns{letter-spacing:.25em}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .tracked-m{letter-spacing:.1em}.swagger-ui .tracked-tight-m{letter-spacing:-.05em}.swagger-ui .tracked-mega-m{letter-spacing:.25em}}@media screen and (min-width:60em){.swagger-ui .tracked-l{letter-spacing:.1em}.swagger-ui .tracked-tight-l{letter-spacing:-.05em}.swagger-ui .tracked-mega-l{letter-spacing:.25em}}.swagger-ui .lh-solid{line-height:1}.swagger-ui .lh-title{line-height:1.25}.swagger-ui .lh-copy{line-height:1.5}@media screen and (min-width:30em){.swagger-ui .lh-solid-ns{line-height:1}.swagger-ui .lh-title-ns{line-height:1.25}.swagger-ui .lh-copy-ns{line-height:1.5}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .lh-solid-m{line-height:1}.swagger-ui .lh-title-m{line-height:1.25}.swagger-ui .lh-copy-m{line-height:1.5}}@media screen and (min-width:60em){.swagger-ui .lh-solid-l{line-height:1}.swagger-ui .lh-title-l{line-height:1.25}.swagger-ui .lh-copy-l{line-height:1.5}}.swagger-ui .link{text-decoration:none}.swagger-ui .link,.swagger-ui .link:link,.swagger-ui .link:visited{transition:color .15s ease-in}.swagger-ui .link:hover{transition:color .15s ease-in}.swagger-ui .link:active{transition:color .15s ease-in}.swagger-ui .link:focus{transition:color .15s ease-in;outline:1px dotted currentColor}.swagger-ui .list{list-style-type:none}.swagger-ui .mw-100{max-width:100%}.swagger-ui .mw1{max-width:1rem}.swagger-ui .mw2{max-width:2rem}.swagger-ui .mw3{max-width:4rem}.swagger-ui .mw4{max-width:8rem}.swagger-ui .mw5{max-width:16rem}.swagger-ui .mw6{max-width:32rem}.swagger-ui .mw7{max-width:48rem}.swagger-ui .mw8{max-width:64rem}.swagger-ui .mw9{max-width:96rem}.swagger-ui .mw-none{max-width:none}@media screen and (min-width:30em){.swagger-ui .mw-100-ns{max-width:100%}.swagger-ui .mw1-ns{max-width:1rem}.swagger-ui .mw2-ns{max-width:2rem}.swagger-ui .mw3-ns{max-width:4rem}.swagger-ui .mw4-ns{max-width:8rem}.swagger-ui .mw5-ns{max-width:16rem}.swagger-ui .mw6-ns{max-width:32rem}.swagger-ui .mw7-ns{max-width:48rem}.swagger-ui .mw8-ns{max-width:64rem}.swagger-ui .mw9-ns{max-width:96rem}.swagger-ui .mw-none-ns{max-width:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .mw-100-m{max-width:100%}.swagger-ui .mw1-m{max-width:1rem}.swagger-ui .mw2-m{max-width:2rem}.swagger-ui .mw3-m{max-width:4rem}.swagger-ui .mw4-m{max-width:8rem}.swagger-ui .mw5-m{max-width:16rem}.swagger-ui .mw6-m{max-width:32rem}.swagger-ui .mw7-m{max-width:48rem}.swagger-ui .mw8-m{max-width:64rem}.swagger-ui .mw9-m{max-width:96rem}.swagger-ui .mw-none-m{max-width:none}}@media screen and (min-width:60em){.swagger-ui .mw-100-l{max-width:100%}.swagger-ui .mw1-l{max-width:1rem}.swagger-ui .mw2-l{max-width:2rem}.swagger-ui .mw3-l{max-width:4rem}.swagger-ui .mw4-l{max-width:8rem}.swagger-ui .mw5-l{max-width:16rem}.swagger-ui .mw6-l{max-width:32rem}.swagger-ui .mw7-l{max-width:48rem}.swagger-ui .mw8-l{max-width:64rem}.swagger-ui .mw9-l{max-width:96rem}.swagger-ui .mw-none-l{max-width:none}}.swagger-ui .w1{width:1rem}.swagger-ui .w2{width:2rem}.swagger-ui .w3{width:4rem}.swagger-ui .w4{width:8rem}.swagger-ui .w5{width:16rem}.swagger-ui .w-10{width:10%}.swagger-ui .w-20{width:20%}.swagger-ui .w-25{width:25%}.swagger-ui .w-30{width:30%}.swagger-ui .w-33{width:33%}.swagger-ui .w-34{width:34%}.swagger-ui .w-40{width:40%}.swagger-ui .w-50{width:50%}.swagger-ui .w-60{width:60%}.swagger-ui .w-70{width:70%}.swagger-ui .w-75{width:75%}.swagger-ui .w-80{width:80%}.swagger-ui .w-90{width:90%}.swagger-ui .w-100{width:100%}.swagger-ui .w-third{width:33.33333%}.swagger-ui .w-two-thirds{width:66.66667%}.swagger-ui .w-auto{width:auto}@media screen and (min-width:30em){.swagger-ui .w1-ns{width:1rem}.swagger-ui .w2-ns{width:2rem}.swagger-ui .w3-ns{width:4rem}.swagger-ui .w4-ns{width:8rem}.swagger-ui .w5-ns{width:16rem}.swagger-ui .w-10-ns{width:10%}.swagger-ui .w-20-ns{width:20%}.swagger-ui .w-25-ns{width:25%}.swagger-ui .w-30-ns{width:30%}.swagger-ui .w-33-ns{width:33%}.swagger-ui .w-34-ns{width:34%}.swagger-ui .w-40-ns{width:40%}.swagger-ui .w-50-ns{width:50%}.swagger-ui .w-60-ns{width:60%}.swagger-ui .w-70-ns{width:70%}.swagger-ui .w-75-ns{width:75%}.swagger-ui .w-80-ns{width:80%}.swagger-ui .w-90-ns{width:90%}.swagger-ui .w-100-ns{width:100%}.swagger-ui .w-third-ns{width:33.33333%}.swagger-ui .w-two-thirds-ns{width:66.66667%}.swagger-ui .w-auto-ns{width:auto}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .w1-m{width:1rem}.swagger-ui .w2-m{width:2rem}.swagger-ui .w3-m{width:4rem}.swagger-ui .w4-m{width:8rem}.swagger-ui .w5-m{width:16rem}.swagger-ui .w-10-m{width:10%}.swagger-ui .w-20-m{width:20%}.swagger-ui .w-25-m{width:25%}.swagger-ui .w-30-m{width:30%}.swagger-ui .w-33-m{width:33%}.swagger-ui .w-34-m{width:34%}.swagger-ui .w-40-m{width:40%}.swagger-ui .w-50-m{width:50%}.swagger-ui .w-60-m{width:60%}.swagger-ui .w-70-m{width:70%}.swagger-ui .w-75-m{width:75%}.swagger-ui .w-80-m{width:80%}.swagger-ui .w-90-m{width:90%}.swagger-ui .w-100-m{width:100%}.swagger-ui .w-third-m{width:33.33333%}.swagger-ui .w-two-thirds-m{width:66.66667%}.swagger-ui .w-auto-m{width:auto}}@media screen and (min-width:60em){.swagger-ui .w1-l{width:1rem}.swagger-ui .w2-l{width:2rem}.swagger-ui .w3-l{width:4rem}.swagger-ui .w4-l{width:8rem}.swagger-ui .w5-l{width:16rem}.swagger-ui .w-10-l{width:10%}.swagger-ui .w-20-l{width:20%}.swagger-ui .w-25-l{width:25%}.swagger-ui .w-30-l{width:30%}.swagger-ui .w-33-l{width:33%}.swagger-ui .w-34-l{width:34%}.swagger-ui .w-40-l{width:40%}.swagger-ui .w-50-l{width:50%}.swagger-ui .w-60-l{width:60%}.swagger-ui .w-70-l{width:70%}.swagger-ui .w-75-l{width:75%}.swagger-ui .w-80-l{width:80%}.swagger-ui .w-90-l{width:90%}.swagger-ui .w-100-l{width:100%}.swagger-ui .w-third-l{width:33.33333%}.swagger-ui .w-two-thirds-l{width:66.66667%}.swagger-ui .w-auto-l{width:auto}}.swagger-ui .overflow-visible{overflow:visible}.swagger-ui .overflow-hidden{overflow:hidden}.swagger-ui .overflow-scroll{overflow:scroll}.swagger-ui .overflow-auto{overflow:auto}.swagger-ui .overflow-x-visible{overflow-x:visible}.swagger-ui .overflow-x-hidden{overflow-x:hidden}.swagger-ui .overflow-x-scroll{overflow-x:scroll}.swagger-ui .overflow-x-auto{overflow-x:auto}.swagger-ui .overflow-y-visible{overflow-y:visible}.swagger-ui .overflow-y-hidden{overflow-y:hidden}.swagger-ui .overflow-y-scroll{overflow-y:scroll}.swagger-ui .overflow-y-auto{overflow-y:auto}@media screen and (min-width:30em){.swagger-ui .overflow-visible-ns{overflow:visible}.swagger-ui .overflow-hidden-ns{overflow:hidden}.swagger-ui .overflow-scroll-ns{overflow:scroll}.swagger-ui .overflow-auto-ns{overflow:auto}.swagger-ui .overflow-x-visible-ns{overflow-x:visible}.swagger-ui .overflow-x-hidden-ns{overflow-x:hidden}.swagger-ui .overflow-x-scroll-ns{overflow-x:scroll}.swagger-ui .overflow-x-auto-ns{overflow-x:auto}.swagger-ui .overflow-y-visible-ns{overflow-y:visible}.swagger-ui .overflow-y-hidden-ns{overflow-y:hidden}.swagger-ui .overflow-y-scroll-ns{overflow-y:scroll}.swagger-ui .overflow-y-auto-ns{overflow-y:auto}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .overflow-visible-m{overflow:visible}.swagger-ui .overflow-hidden-m{overflow:hidden}.swagger-ui .overflow-scroll-m{overflow:scroll}.swagger-ui .overflow-auto-m{overflow:auto}.swagger-ui .overflow-x-visible-m{overflow-x:visible}.swagger-ui .overflow-x-hidden-m{overflow-x:hidden}.swagger-ui .overflow-x-scroll-m{overflow-x:scroll}.swagger-ui .overflow-x-auto-m{overflow-x:auto}.swagger-ui .overflow-y-visible-m{overflow-y:visible}.swagger-ui .overflow-y-hidden-m{overflow-y:hidden}.swagger-ui .overflow-y-scroll-m{overflow-y:scroll}.swagger-ui .overflow-y-auto-m{overflow-y:auto}}@media screen and (min-width:60em){.swagger-ui .overflow-visible-l{overflow:visible}.swagger-ui .overflow-hidden-l{overflow:hidden}.swagger-ui .overflow-scroll-l{overflow:scroll}.swagger-ui .overflow-auto-l{overflow:auto}.swagger-ui .overflow-x-visible-l{overflow-x:visible}.swagger-ui .overflow-x-hidden-l{overflow-x:hidden}.swagger-ui .overflow-x-scroll-l{overflow-x:scroll}.swagger-ui .overflow-x-auto-l{overflow-x:auto}.swagger-ui .overflow-y-visible-l{overflow-y:visible}.swagger-ui .overflow-y-hidden-l{overflow-y:hidden}.swagger-ui .overflow-y-scroll-l{overflow-y:scroll}.swagger-ui .overflow-y-auto-l{overflow-y:auto}}.swagger-ui .static{position:static}.swagger-ui .relative{position:relative}.swagger-ui .absolute{position:absolute}.swagger-ui .fixed{position:fixed}@media screen and (min-width:30em){.swagger-ui .static-ns{position:static}.swagger-ui .relative-ns{position:relative}.swagger-ui .absolute-ns{position:absolute}.swagger-ui .fixed-ns{position:fixed}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .static-m{position:static}.swagger-ui .relative-m{position:relative}.swagger-ui .absolute-m{position:absolute}.swagger-ui .fixed-m{position:fixed}}@media screen and (min-width:60em){.swagger-ui .static-l{position:static}.swagger-ui .relative-l{position:relative}.swagger-ui .absolute-l{position:absolute}.swagger-ui .fixed-l{position:fixed}}.swagger-ui .o-100{opacity:1}.swagger-ui .o-90{opacity:.9}.swagger-ui .o-80{opacity:.8}.swagger-ui .o-70{opacity:.7}.swagger-ui .o-60{opacity:.6}.swagger-ui .o-50{opacity:.5}.swagger-ui .o-40{opacity:.4}.swagger-ui .o-30{opacity:.3}.swagger-ui .o-20{opacity:.2}.swagger-ui .o-10{opacity:.1}.swagger-ui .o-05{opacity:.05}.swagger-ui .o-025{opacity:.025}.swagger-ui .o-0{opacity:0}.swagger-ui .rotate-45{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swagger-ui .rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.swagger-ui .rotate-135{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.swagger-ui .rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.swagger-ui .rotate-225{-webkit-transform:rotate(225deg);transform:rotate(225deg)}.swagger-ui .rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.swagger-ui .rotate-315{-webkit-transform:rotate(315deg);transform:rotate(315deg)}@media screen and (min-width:30em){.swagger-ui .rotate-45-ns{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swagger-ui .rotate-90-ns{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.swagger-ui .rotate-135-ns{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.swagger-ui .rotate-180-ns{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.swagger-ui .rotate-225-ns{-webkit-transform:rotate(225deg);transform:rotate(225deg)}.swagger-ui .rotate-270-ns{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.swagger-ui .rotate-315-ns{-webkit-transform:rotate(315deg);transform:rotate(315deg)}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .rotate-45-m{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swagger-ui .rotate-90-m{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.swagger-ui .rotate-135-m{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.swagger-ui .rotate-180-m{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.swagger-ui .rotate-225-m{-webkit-transform:rotate(225deg);transform:rotate(225deg)}.swagger-ui .rotate-270-m{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.swagger-ui .rotate-315-m{-webkit-transform:rotate(315deg);transform:rotate(315deg)}}@media screen and (min-width:60em){.swagger-ui .rotate-45-l{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swagger-ui .rotate-90-l{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.swagger-ui .rotate-135-l{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.swagger-ui .rotate-180-l{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.swagger-ui .rotate-225-l{-webkit-transform:rotate(225deg);transform:rotate(225deg)}.swagger-ui .rotate-270-l{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.swagger-ui .rotate-315-l{-webkit-transform:rotate(315deg);transform:rotate(315deg)}}.swagger-ui .black-90{color:rgba(0,0,0,.9)}.swagger-ui .black-80{color:rgba(0,0,0,.8)}.swagger-ui .black-70{color:rgba(0,0,0,.7)}.swagger-ui .black-60{color:rgba(0,0,0,.6)}.swagger-ui .black-50{color:rgba(0,0,0,.5)}.swagger-ui .black-40{color:rgba(0,0,0,.4)}.swagger-ui .black-30{color:rgba(0,0,0,.3)}.swagger-ui .black-20{color:rgba(0,0,0,.2)}.swagger-ui .black-10{color:rgba(0,0,0,.1)}.swagger-ui .black-05{color:rgba(0,0,0,.05)}.swagger-ui .white-90{color:hsla(0,0%,100%,.9)}.swagger-ui .white-80{color:hsla(0,0%,100%,.8)}.swagger-ui .white-70{color:hsla(0,0%,100%,.7)}.swagger-ui .white-60{color:hsla(0,0%,100%,.6)}.swagger-ui .white-50{color:hsla(0,0%,100%,.5)}.swagger-ui .white-40{color:hsla(0,0%,100%,.4)}.swagger-ui .white-30{color:hsla(0,0%,100%,.3)}.swagger-ui .white-20{color:hsla(0,0%,100%,.2)}.swagger-ui .white-10{color:hsla(0,0%,100%,.1)}.swagger-ui .black{color:#000}.swagger-ui .near-black{color:#111}.swagger-ui .dark-gray{color:#333}.swagger-ui .mid-gray{color:#555}.swagger-ui .gray{color:#777}.swagger-ui .silver{color:#999}.swagger-ui .light-silver{color:#aaa}.swagger-ui .moon-gray{color:#ccc}.swagger-ui .light-gray{color:#eee}.swagger-ui .near-white{color:#f4f4f4}.swagger-ui .white{color:#fff}.swagger-ui .dark-red{color:#e7040f}.swagger-ui .red{color:#ff4136}.swagger-ui .light-red{color:#ff725c}.swagger-ui .orange{color:#ff6300}.swagger-ui .gold{color:#ffb700}.swagger-ui .yellow{color:gold}.swagger-ui .light-yellow{color:#fbf1a9}.swagger-ui .purple{color:#5e2ca5}.swagger-ui .light-purple{color:#a463f2}.swagger-ui .dark-pink{color:#d5008f}.swagger-ui .hot-pink{color:#ff41b4}.swagger-ui .pink{color:#ff80cc}.swagger-ui .light-pink{color:#ffa3d7}.swagger-ui .dark-green{color:#137752}.swagger-ui .green{color:#19a974}.swagger-ui .light-green{color:#9eebcf}.swagger-ui .navy{color:#001b44}.swagger-ui .dark-blue{color:#00449e}.swagger-ui .blue{color:#357edd}.swagger-ui .light-blue{color:#96ccff}.swagger-ui .lightest-blue{color:#cdecff}.swagger-ui .washed-blue{color:#f6fffe}.swagger-ui .washed-green{color:#e8fdf5}.swagger-ui .washed-yellow{color:#fffceb}.swagger-ui .washed-red{color:#ffdfdf}.swagger-ui .color-inherit{color:inherit}.swagger-ui .bg-black-90{background-color:rgba(0,0,0,.9)}.swagger-ui .bg-black-80{background-color:rgba(0,0,0,.8)}.swagger-ui .bg-black-70{background-color:rgba(0,0,0,.7)}.swagger-ui .bg-black-60{background-color:rgba(0,0,0,.6)}.swagger-ui .bg-black-50{background-color:rgba(0,0,0,.5)}.swagger-ui .bg-black-40{background-color:rgba(0,0,0,.4)}.swagger-ui .bg-black-30{background-color:rgba(0,0,0,.3)}.swagger-ui .bg-black-20{background-color:rgba(0,0,0,.2)}.swagger-ui .bg-black-10{background-color:rgba(0,0,0,.1)}.swagger-ui .bg-black-05{background-color:rgba(0,0,0,.05)}.swagger-ui .bg-white-90{background-color:hsla(0,0%,100%,.9)}.swagger-ui .bg-white-80{background-color:hsla(0,0%,100%,.8)}.swagger-ui .bg-white-70{background-color:hsla(0,0%,100%,.7)}.swagger-ui .bg-white-60{background-color:hsla(0,0%,100%,.6)}.swagger-ui .bg-white-50{background-color:hsla(0,0%,100%,.5)}.swagger-ui .bg-white-40{background-color:hsla(0,0%,100%,.4)}.swagger-ui .bg-white-30{background-color:hsla(0,0%,100%,.3)}.swagger-ui .bg-white-20{background-color:hsla(0,0%,100%,.2)}.swagger-ui .bg-white-10{background-color:hsla(0,0%,100%,.1)}.swagger-ui .bg-black{background-color:#000}.swagger-ui .bg-near-black{background-color:#111}.swagger-ui .bg-dark-gray{background-color:#333}.swagger-ui .bg-mid-gray{background-color:#555}.swagger-ui .bg-gray{background-color:#777}.swagger-ui .bg-silver{background-color:#999}.swagger-ui .bg-light-silver{background-color:#aaa}.swagger-ui .bg-moon-gray{background-color:#ccc}.swagger-ui .bg-light-gray{background-color:#eee}.swagger-ui .bg-near-white{background-color:#f4f4f4}.swagger-ui .bg-white{background-color:#fff}.swagger-ui .bg-transparent{background-color:transparent}.swagger-ui .bg-dark-red{background-color:#e7040f}.swagger-ui .bg-red{background-color:#ff4136}.swagger-ui .bg-light-red{background-color:#ff725c}.swagger-ui .bg-orange{background-color:#ff6300}.swagger-ui .bg-gold{background-color:#ffb700}.swagger-ui .bg-yellow{background-color:gold}.swagger-ui .bg-light-yellow{background-color:#fbf1a9}.swagger-ui .bg-purple{background-color:#5e2ca5}.swagger-ui .bg-light-purple{background-color:#a463f2}.swagger-ui .bg-dark-pink{background-color:#d5008f}.swagger-ui .bg-hot-pink{background-color:#ff41b4}.swagger-ui .bg-pink{background-color:#ff80cc}.swagger-ui .bg-light-pink{background-color:#ffa3d7}.swagger-ui .bg-dark-green{background-color:#137752}.swagger-ui .bg-green{background-color:#19a974}.swagger-ui .bg-light-green{background-color:#9eebcf}.swagger-ui .bg-navy{background-color:#001b44}.swagger-ui .bg-dark-blue{background-color:#00449e}.swagger-ui .bg-blue{background-color:#357edd}.swagger-ui .bg-light-blue{background-color:#96ccff}.swagger-ui .bg-lightest-blue{background-color:#cdecff}.swagger-ui .bg-washed-blue{background-color:#f6fffe}.swagger-ui .bg-washed-green{background-color:#e8fdf5}.swagger-ui .bg-washed-yellow{background-color:#fffceb}.swagger-ui .bg-washed-red{background-color:#ffdfdf}.swagger-ui .bg-inherit{background-color:inherit}.swagger-ui .hover-black:focus,.swagger-ui .hover-black:hover{color:#000}.swagger-ui .hover-near-black:focus,.swagger-ui .hover-near-black:hover{color:#111}.swagger-ui .hover-dark-gray:focus,.swagger-ui .hover-dark-gray:hover{color:#333}.swagger-ui .hover-mid-gray:focus,.swagger-ui .hover-mid-gray:hover{color:#555}.swagger-ui .hover-gray:focus,.swagger-ui .hover-gray:hover{color:#777}.swagger-ui .hover-silver:focus,.swagger-ui .hover-silver:hover{color:#999}.swagger-ui .hover-light-silver:focus,.swagger-ui .hover-light-silver:hover{color:#aaa}.swagger-ui .hover-moon-gray:focus,.swagger-ui .hover-moon-gray:hover{color:#ccc}.swagger-ui .hover-light-gray:focus,.swagger-ui .hover-light-gray:hover{color:#eee}.swagger-ui .hover-near-white:focus,.swagger-ui .hover-near-white:hover{color:#f4f4f4}.swagger-ui .hover-white:focus,.swagger-ui .hover-white:hover{color:#fff}.swagger-ui .hover-black-90:focus,.swagger-ui .hover-black-90:hover{color:rgba(0,0,0,.9)}.swagger-ui .hover-black-80:focus,.swagger-ui .hover-black-80:hover{color:rgba(0,0,0,.8)}.swagger-ui .hover-black-70:focus,.swagger-ui .hover-black-70:hover{color:rgba(0,0,0,.7)}.swagger-ui .hover-black-60:focus,.swagger-ui .hover-black-60:hover{color:rgba(0,0,0,.6)}.swagger-ui .hover-black-50:focus,.swagger-ui .hover-black-50:hover{color:rgba(0,0,0,.5)}.swagger-ui .hover-black-40:focus,.swagger-ui .hover-black-40:hover{color:rgba(0,0,0,.4)}.swagger-ui .hover-black-30:focus,.swagger-ui .hover-black-30:hover{color:rgba(0,0,0,.3)}.swagger-ui .hover-black-20:focus,.swagger-ui .hover-black-20:hover{color:rgba(0,0,0,.2)}.swagger-ui .hover-black-10:focus,.swagger-ui .hover-black-10:hover{color:rgba(0,0,0,.1)}.swagger-ui .hover-white-90:focus,.swagger-ui .hover-white-90:hover{color:hsla(0,0%,100%,.9)}.swagger-ui .hover-white-80:focus,.swagger-ui .hover-white-80:hover{color:hsla(0,0%,100%,.8)}.swagger-ui .hover-white-70:focus,.swagger-ui .hover-white-70:hover{color:hsla(0,0%,100%,.7)}.swagger-ui .hover-white-60:focus,.swagger-ui .hover-white-60:hover{color:hsla(0,0%,100%,.6)}.swagger-ui .hover-white-50:focus,.swagger-ui .hover-white-50:hover{color:hsla(0,0%,100%,.5)}.swagger-ui .hover-white-40:focus,.swagger-ui .hover-white-40:hover{color:hsla(0,0%,100%,.4)}.swagger-ui .hover-white-30:focus,.swagger-ui .hover-white-30:hover{color:hsla(0,0%,100%,.3)}.swagger-ui .hover-white-20:focus,.swagger-ui .hover-white-20:hover{color:hsla(0,0%,100%,.2)}.swagger-ui .hover-white-10:focus,.swagger-ui .hover-white-10:hover{color:hsla(0,0%,100%,.1)}.swagger-ui .hover-inherit:focus,.swagger-ui .hover-inherit:hover{color:inherit}.swagger-ui .hover-bg-black:focus,.swagger-ui .hover-bg-black:hover{background-color:#000}.swagger-ui .hover-bg-near-black:focus,.swagger-ui .hover-bg-near-black:hover{background-color:#111}.swagger-ui .hover-bg-dark-gray:focus,.swagger-ui .hover-bg-dark-gray:hover{background-color:#333}.swagger-ui .hover-bg-mid-gray:focus,.swagger-ui .hover-bg-mid-gray:hover{background-color:#555}.swagger-ui .hover-bg-gray:focus,.swagger-ui .hover-bg-gray:hover{background-color:#777}.swagger-ui .hover-bg-silver:focus,.swagger-ui .hover-bg-silver:hover{background-color:#999}.swagger-ui .hover-bg-light-silver:focus,.swagger-ui .hover-bg-light-silver:hover{background-color:#aaa}.swagger-ui .hover-bg-moon-gray:focus,.swagger-ui .hover-bg-moon-gray:hover{background-color:#ccc}.swagger-ui .hover-bg-light-gray:focus,.swagger-ui .hover-bg-light-gray:hover{background-color:#eee}.swagger-ui .hover-bg-near-white:focus,.swagger-ui .hover-bg-near-white:hover{background-color:#f4f4f4}.swagger-ui .hover-bg-white:focus,.swagger-ui .hover-bg-white:hover{background-color:#fff}.swagger-ui .hover-bg-transparent:focus,.swagger-ui .hover-bg-transparent:hover{background-color:transparent}.swagger-ui .hover-bg-black-90:focus,.swagger-ui .hover-bg-black-90:hover{background-color:rgba(0,0,0,.9)}.swagger-ui .hover-bg-black-80:focus,.swagger-ui .hover-bg-black-80:hover{background-color:rgba(0,0,0,.8)}.swagger-ui .hover-bg-black-70:focus,.swagger-ui .hover-bg-black-70:hover{background-color:rgba(0,0,0,.7)}.swagger-ui .hover-bg-black-60:focus,.swagger-ui .hover-bg-black-60:hover{background-color:rgba(0,0,0,.6)}.swagger-ui .hover-bg-black-50:focus,.swagger-ui .hover-bg-black-50:hover{background-color:rgba(0,0,0,.5)}.swagger-ui .hover-bg-black-40:focus,.swagger-ui .hover-bg-black-40:hover{background-color:rgba(0,0,0,.4)}.swagger-ui .hover-bg-black-30:focus,.swagger-ui .hover-bg-black-30:hover{background-color:rgba(0,0,0,.3)}.swagger-ui .hover-bg-black-20:focus,.swagger-ui .hover-bg-black-20:hover{background-color:rgba(0,0,0,.2)}.swagger-ui .hover-bg-black-10:focus,.swagger-ui .hover-bg-black-10:hover{background-color:rgba(0,0,0,.1)}.swagger-ui .hover-bg-white-90:focus,.swagger-ui .hover-bg-white-90:hover{background-color:hsla(0,0%,100%,.9)}.swagger-ui .hover-bg-white-80:focus,.swagger-ui .hover-bg-white-80:hover{background-color:hsla(0,0%,100%,.8)}.swagger-ui .hover-bg-white-70:focus,.swagger-ui .hover-bg-white-70:hover{background-color:hsla(0,0%,100%,.7)}.swagger-ui .hover-bg-white-60:focus,.swagger-ui .hover-bg-white-60:hover{background-color:hsla(0,0%,100%,.6)}.swagger-ui .hover-bg-white-50:focus,.swagger-ui .hover-bg-white-50:hover{background-color:hsla(0,0%,100%,.5)}.swagger-ui .hover-bg-white-40:focus,.swagger-ui .hover-bg-white-40:hover{background-color:hsla(0,0%,100%,.4)}.swagger-ui .hover-bg-white-30:focus,.swagger-ui .hover-bg-white-30:hover{background-color:hsla(0,0%,100%,.3)}.swagger-ui .hover-bg-white-20:focus,.swagger-ui .hover-bg-white-20:hover{background-color:hsla(0,0%,100%,.2)}.swagger-ui .hover-bg-white-10:focus,.swagger-ui .hover-bg-white-10:hover{background-color:hsla(0,0%,100%,.1)}.swagger-ui .hover-dark-red:focus,.swagger-ui .hover-dark-red:hover{color:#e7040f}.swagger-ui .hover-red:focus,.swagger-ui .hover-red:hover{color:#ff4136}.swagger-ui .hover-light-red:focus,.swagger-ui .hover-light-red:hover{color:#ff725c}.swagger-ui .hover-orange:focus,.swagger-ui .hover-orange:hover{color:#ff6300}.swagger-ui .hover-gold:focus,.swagger-ui .hover-gold:hover{color:#ffb700}.swagger-ui .hover-yellow:focus,.swagger-ui .hover-yellow:hover{color:gold}.swagger-ui .hover-light-yellow:focus,.swagger-ui .hover-light-yellow:hover{color:#fbf1a9}.swagger-ui .hover-purple:focus,.swagger-ui .hover-purple:hover{color:#5e2ca5}.swagger-ui .hover-light-purple:focus,.swagger-ui .hover-light-purple:hover{color:#a463f2}.swagger-ui .hover-dark-pink:focus,.swagger-ui .hover-dark-pink:hover{color:#d5008f}.swagger-ui .hover-hot-pink:focus,.swagger-ui .hover-hot-pink:hover{color:#ff41b4}.swagger-ui .hover-pink:focus,.swagger-ui .hover-pink:hover{color:#ff80cc}.swagger-ui .hover-light-pink:focus,.swagger-ui .hover-light-pink:hover{color:#ffa3d7}.swagger-ui .hover-dark-green:focus,.swagger-ui .hover-dark-green:hover{color:#137752}.swagger-ui .hover-green:focus,.swagger-ui .hover-green:hover{color:#19a974}.swagger-ui .hover-light-green:focus,.swagger-ui .hover-light-green:hover{color:#9eebcf}.swagger-ui .hover-navy:focus,.swagger-ui .hover-navy:hover{color:#001b44}.swagger-ui .hover-dark-blue:focus,.swagger-ui .hover-dark-blue:hover{color:#00449e}.swagger-ui .hover-blue:focus,.swagger-ui .hover-blue:hover{color:#357edd}.swagger-ui .hover-light-blue:focus,.swagger-ui .hover-light-blue:hover{color:#96ccff}.swagger-ui .hover-lightest-blue:focus,.swagger-ui .hover-lightest-blue:hover{color:#cdecff}.swagger-ui .hover-washed-blue:focus,.swagger-ui .hover-washed-blue:hover{color:#f6fffe}.swagger-ui .hover-washed-green:focus,.swagger-ui .hover-washed-green:hover{color:#e8fdf5}.swagger-ui .hover-washed-yellow:focus,.swagger-ui .hover-washed-yellow:hover{color:#fffceb}.swagger-ui .hover-washed-red:focus,.swagger-ui .hover-washed-red:hover{color:#ffdfdf}.swagger-ui .hover-bg-dark-red:focus,.swagger-ui .hover-bg-dark-red:hover{background-color:#e7040f}.swagger-ui .hover-bg-red:focus,.swagger-ui .hover-bg-red:hover{background-color:#ff4136}.swagger-ui .hover-bg-light-red:focus,.swagger-ui .hover-bg-light-red:hover{background-color:#ff725c}.swagger-ui .hover-bg-orange:focus,.swagger-ui .hover-bg-orange:hover{background-color:#ff6300}.swagger-ui .hover-bg-gold:focus,.swagger-ui .hover-bg-gold:hover{background-color:#ffb700}.swagger-ui .hover-bg-yellow:focus,.swagger-ui .hover-bg-yellow:hover{background-color:gold}.swagger-ui .hover-bg-light-yellow:focus,.swagger-ui .hover-bg-light-yellow:hover{background-color:#fbf1a9}.swagger-ui .hover-bg-purple:focus,.swagger-ui .hover-bg-purple:hover{background-color:#5e2ca5}.swagger-ui .hover-bg-light-purple:focus,.swagger-ui .hover-bg-light-purple:hover{background-color:#a463f2}.swagger-ui .hover-bg-dark-pink:focus,.swagger-ui .hover-bg-dark-pink:hover{background-color:#d5008f}.swagger-ui .hover-bg-hot-pink:focus,.swagger-ui .hover-bg-hot-pink:hover{background-color:#ff41b4}.swagger-ui .hover-bg-pink:focus,.swagger-ui .hover-bg-pink:hover{background-color:#ff80cc}.swagger-ui .hover-bg-light-pink:focus,.swagger-ui .hover-bg-light-pink:hover{background-color:#ffa3d7}.swagger-ui .hover-bg-dark-green:focus,.swagger-ui .hover-bg-dark-green:hover{background-color:#137752}.swagger-ui .hover-bg-green:focus,.swagger-ui .hover-bg-green:hover{background-color:#19a974}.swagger-ui .hover-bg-light-green:focus,.swagger-ui .hover-bg-light-green:hover{background-color:#9eebcf}.swagger-ui .hover-bg-navy:focus,.swagger-ui .hover-bg-navy:hover{background-color:#001b44}.swagger-ui .hover-bg-dark-blue:focus,.swagger-ui .hover-bg-dark-blue:hover{background-color:#00449e}.swagger-ui .hover-bg-blue:focus,.swagger-ui .hover-bg-blue:hover{background-color:#357edd}.swagger-ui .hover-bg-light-blue:focus,.swagger-ui .hover-bg-light-blue:hover{background-color:#96ccff}.swagger-ui .hover-bg-lightest-blue:focus,.swagger-ui .hover-bg-lightest-blue:hover{background-color:#cdecff}.swagger-ui .hover-bg-washed-blue:focus,.swagger-ui .hover-bg-washed-blue:hover{background-color:#f6fffe}.swagger-ui .hover-bg-washed-green:focus,.swagger-ui .hover-bg-washed-green:hover{background-color:#e8fdf5}.swagger-ui .hover-bg-washed-yellow:focus,.swagger-ui .hover-bg-washed-yellow:hover{background-color:#fffceb}.swagger-ui .hover-bg-washed-red:focus,.swagger-ui .hover-bg-washed-red:hover{background-color:#ffdfdf}.swagger-ui .hover-bg-inherit:focus,.swagger-ui .hover-bg-inherit:hover{background-color:inherit}.swagger-ui .pa0{padding:0}.swagger-ui .pa1{padding:.25rem}.swagger-ui .pa2{padding:.5rem}.swagger-ui .pa3{padding:1rem}.swagger-ui .pa4{padding:2rem}.swagger-ui .pa5{padding:4rem}.swagger-ui .pa6{padding:8rem}.swagger-ui .pa7{padding:16rem}.swagger-ui .pl0{padding-left:0}.swagger-ui .pl1{padding-left:.25rem}.swagger-ui .pl2{padding-left:.5rem}.swagger-ui .pl3{padding-left:1rem}.swagger-ui .pl4{padding-left:2rem}.swagger-ui .pl5{padding-left:4rem}.swagger-ui .pl6{padding-left:8rem}.swagger-ui .pl7{padding-left:16rem}.swagger-ui .pr0{padding-right:0}.swagger-ui .pr1{padding-right:.25rem}.swagger-ui .pr2{padding-right:.5rem}.swagger-ui .pr3{padding-right:1rem}.swagger-ui .pr4{padding-right:2rem}.swagger-ui .pr5{padding-right:4rem}.swagger-ui .pr6{padding-right:8rem}.swagger-ui .pr7{padding-right:16rem}.swagger-ui .pb0{padding-bottom:0}.swagger-ui .pb1{padding-bottom:.25rem}.swagger-ui .pb2{padding-bottom:.5rem}.swagger-ui .pb3{padding-bottom:1rem}.swagger-ui .pb4{padding-bottom:2rem}.swagger-ui .pb5{padding-bottom:4rem}.swagger-ui .pb6{padding-bottom:8rem}.swagger-ui .pb7{padding-bottom:16rem}.swagger-ui .pt0{padding-top:0}.swagger-ui .pt1{padding-top:.25rem}.swagger-ui .pt2{padding-top:.5rem}.swagger-ui .pt3{padding-top:1rem}.swagger-ui .pt4{padding-top:2rem}.swagger-ui .pt5{padding-top:4rem}.swagger-ui .pt6{padding-top:8rem}.swagger-ui .pt7{padding-top:16rem}.swagger-ui .pv0{padding-top:0;padding-bottom:0}.swagger-ui .pv1{padding-top:.25rem;padding-bottom:.25rem}.swagger-ui .pv2{padding-top:.5rem;padding-bottom:.5rem}.swagger-ui .pv3{padding-top:1rem;padding-bottom:1rem}.swagger-ui .pv4{padding-top:2rem;padding-bottom:2rem}.swagger-ui .pv5{padding-top:4rem;padding-bottom:4rem}.swagger-ui .pv6{padding-top:8rem;padding-bottom:8rem}.swagger-ui .pv7{padding-top:16rem;padding-bottom:16rem}.swagger-ui .ph0{padding-left:0;padding-right:0}.swagger-ui .ph1{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0{margin:0}.swagger-ui .ma1{margin:.25rem}.swagger-ui .ma2{margin:.5rem}.swagger-ui .ma3{margin:1rem}.swagger-ui .ma4{margin:2rem}.swagger-ui .ma5{margin:4rem}.swagger-ui .ma6{margin:8rem}.swagger-ui .ma7{margin:16rem}.swagger-ui .ml0{margin-left:0}.swagger-ui .ml1{margin-left:.25rem}.swagger-ui .ml2{margin-left:.5rem}.swagger-ui .ml3{margin-left:1rem}.swagger-ui .ml4{margin-left:2rem}.swagger-ui .ml5{margin-left:4rem}.swagger-ui .ml6{margin-left:8rem}.swagger-ui .ml7{margin-left:16rem}.swagger-ui .mr0{margin-right:0}.swagger-ui .mr1{margin-right:.25rem}.swagger-ui .mr2{margin-right:.5rem}.swagger-ui .mr3{margin-right:1rem}.swagger-ui .mr4{margin-right:2rem}.swagger-ui .mr5{margin-right:4rem}.swagger-ui .mr6{margin-right:8rem}.swagger-ui .mr7{margin-right:16rem}.swagger-ui .mb0{margin-bottom:0}.swagger-ui .mb1{margin-bottom:.25rem}.swagger-ui .mb2{margin-bottom:.5rem}.swagger-ui .mb3{margin-bottom:1rem}.swagger-ui .mb4{margin-bottom:2rem}.swagger-ui .mb5{margin-bottom:4rem}.swagger-ui .mb6{margin-bottom:8rem}.swagger-ui .mb7{margin-bottom:16rem}.swagger-ui .mt0{margin-top:0}.swagger-ui .mt1{margin-top:.25rem}.swagger-ui .mt2{margin-top:.5rem}.swagger-ui .mt3{margin-top:1rem}.swagger-ui .mt4{margin-top:2rem}.swagger-ui .mt5{margin-top:4rem}.swagger-ui .mt6{margin-top:8rem}.swagger-ui .mt7{margin-top:16rem}.swagger-ui .mv0{margin-top:0;margin-bottom:0}.swagger-ui .mv1{margin-top:.25rem;margin-bottom:.25rem}.swagger-ui .mv2{margin-top:.5rem;margin-bottom:.5rem}.swagger-ui .mv3{margin-top:1rem;margin-bottom:1rem}.swagger-ui .mv4{margin-top:2rem;margin-bottom:2rem}.swagger-ui .mv5{margin-top:4rem;margin-bottom:4rem}.swagger-ui .mv6{margin-top:8rem;margin-bottom:8rem}.swagger-ui .mv7{margin-top:16rem;margin-bottom:16rem}.swagger-ui .mh0{margin-left:0;margin-right:0}.swagger-ui .mh1{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7{margin-left:16rem;margin-right:16rem}@media screen and (min-width:30em){.swagger-ui .pa0-ns{padding:0}.swagger-ui .pa1-ns{padding:.25rem}.swagger-ui .pa2-ns{padding:.5rem}.swagger-ui .pa3-ns{padding:1rem}.swagger-ui .pa4-ns{padding:2rem}.swagger-ui .pa5-ns{padding:4rem}.swagger-ui .pa6-ns{padding:8rem}.swagger-ui .pa7-ns{padding:16rem}.swagger-ui .pl0-ns{padding-left:0}.swagger-ui .pl1-ns{padding-left:.25rem}.swagger-ui .pl2-ns{padding-left:.5rem}.swagger-ui .pl3-ns{padding-left:1rem}.swagger-ui .pl4-ns{padding-left:2rem}.swagger-ui .pl5-ns{padding-left:4rem}.swagger-ui .pl6-ns{padding-left:8rem}.swagger-ui .pl7-ns{padding-left:16rem}.swagger-ui .pr0-ns{padding-right:0}.swagger-ui .pr1-ns{padding-right:.25rem}.swagger-ui .pr2-ns{padding-right:.5rem}.swagger-ui .pr3-ns{padding-right:1rem}.swagger-ui .pr4-ns{padding-right:2rem}.swagger-ui .pr5-ns{padding-right:4rem}.swagger-ui .pr6-ns{padding-right:8rem}.swagger-ui .pr7-ns{padding-right:16rem}.swagger-ui .pb0-ns{padding-bottom:0}.swagger-ui .pb1-ns{padding-bottom:.25rem}.swagger-ui .pb2-ns{padding-bottom:.5rem}.swagger-ui .pb3-ns{padding-bottom:1rem}.swagger-ui .pb4-ns{padding-bottom:2rem}.swagger-ui .pb5-ns{padding-bottom:4rem}.swagger-ui .pb6-ns{padding-bottom:8rem}.swagger-ui .pb7-ns{padding-bottom:16rem}.swagger-ui .pt0-ns{padding-top:0}.swagger-ui .pt1-ns{padding-top:.25rem}.swagger-ui .pt2-ns{padding-top:.5rem}.swagger-ui .pt3-ns{padding-top:1rem}.swagger-ui .pt4-ns{padding-top:2rem}.swagger-ui .pt5-ns{padding-top:4rem}.swagger-ui .pt6-ns{padding-top:8rem}.swagger-ui .pt7-ns{padding-top:16rem}.swagger-ui .pv0-ns{padding-top:0;padding-bottom:0}.swagger-ui .pv1-ns{padding-top:.25rem;padding-bottom:.25rem}.swagger-ui .pv2-ns{padding-top:.5rem;padding-bottom:.5rem}.swagger-ui .pv3-ns{padding-top:1rem;padding-bottom:1rem}.swagger-ui .pv4-ns{padding-top:2rem;padding-bottom:2rem}.swagger-ui .pv5-ns{padding-top:4rem;padding-bottom:4rem}.swagger-ui .pv6-ns{padding-top:8rem;padding-bottom:8rem}.swagger-ui .pv7-ns{padding-top:16rem;padding-bottom:16rem}.swagger-ui .ph0-ns{padding-left:0;padding-right:0}.swagger-ui .ph1-ns{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-ns{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-ns{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-ns{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-ns{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-ns{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-ns{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-ns{margin:0}.swagger-ui .ma1-ns{margin:.25rem}.swagger-ui .ma2-ns{margin:.5rem}.swagger-ui .ma3-ns{margin:1rem}.swagger-ui .ma4-ns{margin:2rem}.swagger-ui .ma5-ns{margin:4rem}.swagger-ui .ma6-ns{margin:8rem}.swagger-ui .ma7-ns{margin:16rem}.swagger-ui .ml0-ns{margin-left:0}.swagger-ui .ml1-ns{margin-left:.25rem}.swagger-ui .ml2-ns{margin-left:.5rem}.swagger-ui .ml3-ns{margin-left:1rem}.swagger-ui .ml4-ns{margin-left:2rem}.swagger-ui .ml5-ns{margin-left:4rem}.swagger-ui .ml6-ns{margin-left:8rem}.swagger-ui .ml7-ns{margin-left:16rem}.swagger-ui .mr0-ns{margin-right:0}.swagger-ui .mr1-ns{margin-right:.25rem}.swagger-ui .mr2-ns{margin-right:.5rem}.swagger-ui .mr3-ns{margin-right:1rem}.swagger-ui .mr4-ns{margin-right:2rem}.swagger-ui .mr5-ns{margin-right:4rem}.swagger-ui .mr6-ns{margin-right:8rem}.swagger-ui .mr7-ns{margin-right:16rem}.swagger-ui .mb0-ns{margin-bottom:0}.swagger-ui .mb1-ns{margin-bottom:.25rem}.swagger-ui .mb2-ns{margin-bottom:.5rem}.swagger-ui .mb3-ns{margin-bottom:1rem}.swagger-ui .mb4-ns{margin-bottom:2rem}.swagger-ui .mb5-ns{margin-bottom:4rem}.swagger-ui .mb6-ns{margin-bottom:8rem}.swagger-ui .mb7-ns{margin-bottom:16rem}.swagger-ui .mt0-ns{margin-top:0}.swagger-ui .mt1-ns{margin-top:.25rem}.swagger-ui .mt2-ns{margin-top:.5rem}.swagger-ui .mt3-ns{margin-top:1rem}.swagger-ui .mt4-ns{margin-top:2rem}.swagger-ui .mt5-ns{margin-top:4rem}.swagger-ui .mt6-ns{margin-top:8rem}.swagger-ui .mt7-ns{margin-top:16rem}.swagger-ui .mv0-ns{margin-top:0;margin-bottom:0}.swagger-ui .mv1-ns{margin-top:.25rem;margin-bottom:.25rem}.swagger-ui .mv2-ns{margin-top:.5rem;margin-bottom:.5rem}.swagger-ui .mv3-ns{margin-top:1rem;margin-bottom:1rem}.swagger-ui .mv4-ns{margin-top:2rem;margin-bottom:2rem}.swagger-ui .mv5-ns{margin-top:4rem;margin-bottom:4rem}.swagger-ui .mv6-ns{margin-top:8rem;margin-bottom:8rem}.swagger-ui .mv7-ns{margin-top:16rem;margin-bottom:16rem}.swagger-ui .mh0-ns{margin-left:0;margin-right:0}.swagger-ui .mh1-ns{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-ns{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-ns{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-ns{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-ns{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-ns{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-ns{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .pa0-m{padding:0}.swagger-ui .pa1-m{padding:.25rem}.swagger-ui .pa2-m{padding:.5rem}.swagger-ui .pa3-m{padding:1rem}.swagger-ui .pa4-m{padding:2rem}.swagger-ui .pa5-m{padding:4rem}.swagger-ui .pa6-m{padding:8rem}.swagger-ui .pa7-m{padding:16rem}.swagger-ui .pl0-m{padding-left:0}.swagger-ui .pl1-m{padding-left:.25rem}.swagger-ui .pl2-m{padding-left:.5rem}.swagger-ui .pl3-m{padding-left:1rem}.swagger-ui .pl4-m{padding-left:2rem}.swagger-ui .pl5-m{padding-left:4rem}.swagger-ui .pl6-m{padding-left:8rem}.swagger-ui .pl7-m{padding-left:16rem}.swagger-ui .pr0-m{padding-right:0}.swagger-ui .pr1-m{padding-right:.25rem}.swagger-ui .pr2-m{padding-right:.5rem}.swagger-ui .pr3-m{padding-right:1rem}.swagger-ui .pr4-m{padding-right:2rem}.swagger-ui .pr5-m{padding-right:4rem}.swagger-ui .pr6-m{padding-right:8rem}.swagger-ui .pr7-m{padding-right:16rem}.swagger-ui .pb0-m{padding-bottom:0}.swagger-ui .pb1-m{padding-bottom:.25rem}.swagger-ui .pb2-m{padding-bottom:.5rem}.swagger-ui .pb3-m{padding-bottom:1rem}.swagger-ui .pb4-m{padding-bottom:2rem}.swagger-ui .pb5-m{padding-bottom:4rem}.swagger-ui .pb6-m{padding-bottom:8rem}.swagger-ui .pb7-m{padding-bottom:16rem}.swagger-ui .pt0-m{padding-top:0}.swagger-ui .pt1-m{padding-top:.25rem}.swagger-ui .pt2-m{padding-top:.5rem}.swagger-ui .pt3-m{padding-top:1rem}.swagger-ui .pt4-m{padding-top:2rem}.swagger-ui .pt5-m{padding-top:4rem}.swagger-ui .pt6-m{padding-top:8rem}.swagger-ui .pt7-m{padding-top:16rem}.swagger-ui .pv0-m{padding-top:0;padding-bottom:0}.swagger-ui .pv1-m{padding-top:.25rem;padding-bottom:.25rem}.swagger-ui .pv2-m{padding-top:.5rem;padding-bottom:.5rem}.swagger-ui .pv3-m{padding-top:1rem;padding-bottom:1rem}.swagger-ui .pv4-m{padding-top:2rem;padding-bottom:2rem}.swagger-ui .pv5-m{padding-top:4rem;padding-bottom:4rem}.swagger-ui .pv6-m{padding-top:8rem;padding-bottom:8rem}.swagger-ui .pv7-m{padding-top:16rem;padding-bottom:16rem}.swagger-ui .ph0-m{padding-left:0;padding-right:0}.swagger-ui .ph1-m{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-m{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-m{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-m{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-m{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-m{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-m{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-m{margin:0}.swagger-ui .ma1-m{margin:.25rem}.swagger-ui .ma2-m{margin:.5rem}.swagger-ui .ma3-m{margin:1rem}.swagger-ui .ma4-m{margin:2rem}.swagger-ui .ma5-m{margin:4rem}.swagger-ui .ma6-m{margin:8rem}.swagger-ui .ma7-m{margin:16rem}.swagger-ui .ml0-m{margin-left:0}.swagger-ui .ml1-m{margin-left:.25rem}.swagger-ui .ml2-m{margin-left:.5rem}.swagger-ui .ml3-m{margin-left:1rem}.swagger-ui .ml4-m{margin-left:2rem}.swagger-ui .ml5-m{margin-left:4rem}.swagger-ui .ml6-m{margin-left:8rem}.swagger-ui .ml7-m{margin-left:16rem}.swagger-ui .mr0-m{margin-right:0}.swagger-ui .mr1-m{margin-right:.25rem}.swagger-ui .mr2-m{margin-right:.5rem}.swagger-ui .mr3-m{margin-right:1rem}.swagger-ui .mr4-m{margin-right:2rem}.swagger-ui .mr5-m{margin-right:4rem}.swagger-ui .mr6-m{margin-right:8rem}.swagger-ui .mr7-m{margin-right:16rem}.swagger-ui .mb0-m{margin-bottom:0}.swagger-ui .mb1-m{margin-bottom:.25rem}.swagger-ui .mb2-m{margin-bottom:.5rem}.swagger-ui .mb3-m{margin-bottom:1rem}.swagger-ui .mb4-m{margin-bottom:2rem}.swagger-ui .mb5-m{margin-bottom:4rem}.swagger-ui .mb6-m{margin-bottom:8rem}.swagger-ui .mb7-m{margin-bottom:16rem}.swagger-ui .mt0-m{margin-top:0}.swagger-ui .mt1-m{margin-top:.25rem}.swagger-ui .mt2-m{margin-top:.5rem}.swagger-ui .mt3-m{margin-top:1rem}.swagger-ui .mt4-m{margin-top:2rem}.swagger-ui .mt5-m{margin-top:4rem}.swagger-ui .mt6-m{margin-top:8rem}.swagger-ui .mt7-m{margin-top:16rem}.swagger-ui .mv0-m{margin-top:0;margin-bottom:0}.swagger-ui .mv1-m{margin-top:.25rem;margin-bottom:.25rem}.swagger-ui .mv2-m{margin-top:.5rem;margin-bottom:.5rem}.swagger-ui .mv3-m{margin-top:1rem;margin-bottom:1rem}.swagger-ui .mv4-m{margin-top:2rem;margin-bottom:2rem}.swagger-ui .mv5-m{margin-top:4rem;margin-bottom:4rem}.swagger-ui .mv6-m{margin-top:8rem;margin-bottom:8rem}.swagger-ui .mv7-m{margin-top:16rem;margin-bottom:16rem}.swagger-ui .mh0-m{margin-left:0;margin-right:0}.swagger-ui .mh1-m{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-m{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-m{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-m{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-m{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-m{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-m{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:60em){.swagger-ui .pa0-l{padding:0}.swagger-ui .pa1-l{padding:.25rem}.swagger-ui .pa2-l{padding:.5rem}.swagger-ui .pa3-l{padding:1rem}.swagger-ui .pa4-l{padding:2rem}.swagger-ui .pa5-l{padding:4rem}.swagger-ui .pa6-l{padding:8rem}.swagger-ui .pa7-l{padding:16rem}.swagger-ui .pl0-l{padding-left:0}.swagger-ui .pl1-l{padding-left:.25rem}.swagger-ui .pl2-l{padding-left:.5rem}.swagger-ui .pl3-l{padding-left:1rem}.swagger-ui .pl4-l{padding-left:2rem}.swagger-ui .pl5-l{padding-left:4rem}.swagger-ui .pl6-l{padding-left:8rem}.swagger-ui .pl7-l{padding-left:16rem}.swagger-ui .pr0-l{padding-right:0}.swagger-ui .pr1-l{padding-right:.25rem}.swagger-ui .pr2-l{padding-right:.5rem}.swagger-ui .pr3-l{padding-right:1rem}.swagger-ui .pr4-l{padding-right:2rem}.swagger-ui .pr5-l{padding-right:4rem}.swagger-ui .pr6-l{padding-right:8rem}.swagger-ui .pr7-l{padding-right:16rem}.swagger-ui .pb0-l{padding-bottom:0}.swagger-ui .pb1-l{padding-bottom:.25rem}.swagger-ui .pb2-l{padding-bottom:.5rem}.swagger-ui .pb3-l{padding-bottom:1rem}.swagger-ui .pb4-l{padding-bottom:2rem}.swagger-ui .pb5-l{padding-bottom:4rem}.swagger-ui .pb6-l{padding-bottom:8rem}.swagger-ui .pb7-l{padding-bottom:16rem}.swagger-ui .pt0-l{padding-top:0}.swagger-ui .pt1-l{padding-top:.25rem}.swagger-ui .pt2-l{padding-top:.5rem}.swagger-ui .pt3-l{padding-top:1rem}.swagger-ui .pt4-l{padding-top:2rem}.swagger-ui .pt5-l{padding-top:4rem}.swagger-ui .pt6-l{padding-top:8rem}.swagger-ui .pt7-l{padding-top:16rem}.swagger-ui .pv0-l{padding-top:0;padding-bottom:0}.swagger-ui .pv1-l{padding-top:.25rem;padding-bottom:.25rem}.swagger-ui .pv2-l{padding-top:.5rem;padding-bottom:.5rem}.swagger-ui .pv3-l{padding-top:1rem;padding-bottom:1rem}.swagger-ui .pv4-l{padding-top:2rem;padding-bottom:2rem}.swagger-ui .pv5-l{padding-top:4rem;padding-bottom:4rem}.swagger-ui .pv6-l{padding-top:8rem;padding-bottom:8rem}.swagger-ui .pv7-l{padding-top:16rem;padding-bottom:16rem}.swagger-ui .ph0-l{padding-left:0;padding-right:0}.swagger-ui .ph1-l{padding-left:.25rem;padding-right:.25rem}.swagger-ui .ph2-l{padding-left:.5rem;padding-right:.5rem}.swagger-ui .ph3-l{padding-left:1rem;padding-right:1rem}.swagger-ui .ph4-l{padding-left:2rem;padding-right:2rem}.swagger-ui .ph5-l{padding-left:4rem;padding-right:4rem}.swagger-ui .ph6-l{padding-left:8rem;padding-right:8rem}.swagger-ui .ph7-l{padding-left:16rem;padding-right:16rem}.swagger-ui .ma0-l{margin:0}.swagger-ui .ma1-l{margin:.25rem}.swagger-ui .ma2-l{margin:.5rem}.swagger-ui .ma3-l{margin:1rem}.swagger-ui .ma4-l{margin:2rem}.swagger-ui .ma5-l{margin:4rem}.swagger-ui .ma6-l{margin:8rem}.swagger-ui .ma7-l{margin:16rem}.swagger-ui .ml0-l{margin-left:0}.swagger-ui .ml1-l{margin-left:.25rem}.swagger-ui .ml2-l{margin-left:.5rem}.swagger-ui .ml3-l{margin-left:1rem}.swagger-ui .ml4-l{margin-left:2rem}.swagger-ui .ml5-l{margin-left:4rem}.swagger-ui .ml6-l{margin-left:8rem}.swagger-ui .ml7-l{margin-left:16rem}.swagger-ui .mr0-l{margin-right:0}.swagger-ui .mr1-l{margin-right:.25rem}.swagger-ui .mr2-l{margin-right:.5rem}.swagger-ui .mr3-l{margin-right:1rem}.swagger-ui .mr4-l{margin-right:2rem}.swagger-ui .mr5-l{margin-right:4rem}.swagger-ui .mr6-l{margin-right:8rem}.swagger-ui .mr7-l{margin-right:16rem}.swagger-ui .mb0-l{margin-bottom:0}.swagger-ui .mb1-l{margin-bottom:.25rem}.swagger-ui .mb2-l{margin-bottom:.5rem}.swagger-ui .mb3-l{margin-bottom:1rem}.swagger-ui .mb4-l{margin-bottom:2rem}.swagger-ui .mb5-l{margin-bottom:4rem}.swagger-ui .mb6-l{margin-bottom:8rem}.swagger-ui .mb7-l{margin-bottom:16rem}.swagger-ui .mt0-l{margin-top:0}.swagger-ui .mt1-l{margin-top:.25rem}.swagger-ui .mt2-l{margin-top:.5rem}.swagger-ui .mt3-l{margin-top:1rem}.swagger-ui .mt4-l{margin-top:2rem}.swagger-ui .mt5-l{margin-top:4rem}.swagger-ui .mt6-l{margin-top:8rem}.swagger-ui .mt7-l{margin-top:16rem}.swagger-ui .mv0-l{margin-top:0;margin-bottom:0}.swagger-ui .mv1-l{margin-top:.25rem;margin-bottom:.25rem}.swagger-ui .mv2-l{margin-top:.5rem;margin-bottom:.5rem}.swagger-ui .mv3-l{margin-top:1rem;margin-bottom:1rem}.swagger-ui .mv4-l{margin-top:2rem;margin-bottom:2rem}.swagger-ui .mv5-l{margin-top:4rem;margin-bottom:4rem}.swagger-ui .mv6-l{margin-top:8rem;margin-bottom:8rem}.swagger-ui .mv7-l{margin-top:16rem;margin-bottom:16rem}.swagger-ui .mh0-l{margin-left:0;margin-right:0}.swagger-ui .mh1-l{margin-left:.25rem;margin-right:.25rem}.swagger-ui .mh2-l{margin-left:.5rem;margin-right:.5rem}.swagger-ui .mh3-l{margin-left:1rem;margin-right:1rem}.swagger-ui .mh4-l{margin-left:2rem;margin-right:2rem}.swagger-ui .mh5-l{margin-left:4rem;margin-right:4rem}.swagger-ui .mh6-l{margin-left:8rem;margin-right:8rem}.swagger-ui .mh7-l{margin-left:16rem;margin-right:16rem}}.swagger-ui .na1{margin:-.25rem}.swagger-ui .na2{margin:-.5rem}.swagger-ui .na3{margin:-1rem}.swagger-ui .na4{margin:-2rem}.swagger-ui .na5{margin:-4rem}.swagger-ui .na6{margin:-8rem}.swagger-ui .na7{margin:-16rem}.swagger-ui .nl1{margin-left:-.25rem}.swagger-ui .nl2{margin-left:-.5rem}.swagger-ui .nl3{margin-left:-1rem}.swagger-ui .nl4{margin-left:-2rem}.swagger-ui .nl5{margin-left:-4rem}.swagger-ui .nl6{margin-left:-8rem}.swagger-ui .nl7{margin-left:-16rem}.swagger-ui .nr1{margin-right:-.25rem}.swagger-ui .nr2{margin-right:-.5rem}.swagger-ui .nr3{margin-right:-1rem}.swagger-ui .nr4{margin-right:-2rem}.swagger-ui .nr5{margin-right:-4rem}.swagger-ui .nr6{margin-right:-8rem}.swagger-ui .nr7{margin-right:-16rem}.swagger-ui .nb1{margin-bottom:-.25rem}.swagger-ui .nb2{margin-bottom:-.5rem}.swagger-ui .nb3{margin-bottom:-1rem}.swagger-ui .nb4{margin-bottom:-2rem}.swagger-ui .nb5{margin-bottom:-4rem}.swagger-ui .nb6{margin-bottom:-8rem}.swagger-ui .nb7{margin-bottom:-16rem}.swagger-ui .nt1{margin-top:-.25rem}.swagger-ui .nt2{margin-top:-.5rem}.swagger-ui .nt3{margin-top:-1rem}.swagger-ui .nt4{margin-top:-2rem}.swagger-ui .nt5{margin-top:-4rem}.swagger-ui .nt6{margin-top:-8rem}.swagger-ui .nt7{margin-top:-16rem}@media screen and (min-width:30em){.swagger-ui .na1-ns{margin:-.25rem}.swagger-ui .na2-ns{margin:-.5rem}.swagger-ui .na3-ns{margin:-1rem}.swagger-ui .na4-ns{margin:-2rem}.swagger-ui .na5-ns{margin:-4rem}.swagger-ui .na6-ns{margin:-8rem}.swagger-ui .na7-ns{margin:-16rem}.swagger-ui .nl1-ns{margin-left:-.25rem}.swagger-ui .nl2-ns{margin-left:-.5rem}.swagger-ui .nl3-ns{margin-left:-1rem}.swagger-ui .nl4-ns{margin-left:-2rem}.swagger-ui .nl5-ns{margin-left:-4rem}.swagger-ui .nl6-ns{margin-left:-8rem}.swagger-ui .nl7-ns{margin-left:-16rem}.swagger-ui .nr1-ns{margin-right:-.25rem}.swagger-ui .nr2-ns{margin-right:-.5rem}.swagger-ui .nr3-ns{margin-right:-1rem}.swagger-ui .nr4-ns{margin-right:-2rem}.swagger-ui .nr5-ns{margin-right:-4rem}.swagger-ui .nr6-ns{margin-right:-8rem}.swagger-ui .nr7-ns{margin-right:-16rem}.swagger-ui .nb1-ns{margin-bottom:-.25rem}.swagger-ui .nb2-ns{margin-bottom:-.5rem}.swagger-ui .nb3-ns{margin-bottom:-1rem}.swagger-ui .nb4-ns{margin-bottom:-2rem}.swagger-ui .nb5-ns{margin-bottom:-4rem}.swagger-ui .nb6-ns{margin-bottom:-8rem}.swagger-ui .nb7-ns{margin-bottom:-16rem}.swagger-ui .nt1-ns{margin-top:-.25rem}.swagger-ui .nt2-ns{margin-top:-.5rem}.swagger-ui .nt3-ns{margin-top:-1rem}.swagger-ui .nt4-ns{margin-top:-2rem}.swagger-ui .nt5-ns{margin-top:-4rem}.swagger-ui .nt6-ns{margin-top:-8rem}.swagger-ui .nt7-ns{margin-top:-16rem}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .na1-m{margin:-.25rem}.swagger-ui .na2-m{margin:-.5rem}.swagger-ui .na3-m{margin:-1rem}.swagger-ui .na4-m{margin:-2rem}.swagger-ui .na5-m{margin:-4rem}.swagger-ui .na6-m{margin:-8rem}.swagger-ui .na7-m{margin:-16rem}.swagger-ui .nl1-m{margin-left:-.25rem}.swagger-ui .nl2-m{margin-left:-.5rem}.swagger-ui .nl3-m{margin-left:-1rem}.swagger-ui .nl4-m{margin-left:-2rem}.swagger-ui .nl5-m{margin-left:-4rem}.swagger-ui .nl6-m{margin-left:-8rem}.swagger-ui .nl7-m{margin-left:-16rem}.swagger-ui .nr1-m{margin-right:-.25rem}.swagger-ui .nr2-m{margin-right:-.5rem}.swagger-ui .nr3-m{margin-right:-1rem}.swagger-ui .nr4-m{margin-right:-2rem}.swagger-ui .nr5-m{margin-right:-4rem}.swagger-ui .nr6-m{margin-right:-8rem}.swagger-ui .nr7-m{margin-right:-16rem}.swagger-ui .nb1-m{margin-bottom:-.25rem}.swagger-ui .nb2-m{margin-bottom:-.5rem}.swagger-ui .nb3-m{margin-bottom:-1rem}.swagger-ui .nb4-m{margin-bottom:-2rem}.swagger-ui .nb5-m{margin-bottom:-4rem}.swagger-ui .nb6-m{margin-bottom:-8rem}.swagger-ui .nb7-m{margin-bottom:-16rem}.swagger-ui .nt1-m{margin-top:-.25rem}.swagger-ui .nt2-m{margin-top:-.5rem}.swagger-ui .nt3-m{margin-top:-1rem}.swagger-ui .nt4-m{margin-top:-2rem}.swagger-ui .nt5-m{margin-top:-4rem}.swagger-ui .nt6-m{margin-top:-8rem}.swagger-ui .nt7-m{margin-top:-16rem}}@media screen and (min-width:60em){.swagger-ui .na1-l{margin:-.25rem}.swagger-ui .na2-l{margin:-.5rem}.swagger-ui .na3-l{margin:-1rem}.swagger-ui .na4-l{margin:-2rem}.swagger-ui .na5-l{margin:-4rem}.swagger-ui .na6-l{margin:-8rem}.swagger-ui .na7-l{margin:-16rem}.swagger-ui .nl1-l{margin-left:-.25rem}.swagger-ui .nl2-l{margin-left:-.5rem}.swagger-ui .nl3-l{margin-left:-1rem}.swagger-ui .nl4-l{margin-left:-2rem}.swagger-ui .nl5-l{margin-left:-4rem}.swagger-ui .nl6-l{margin-left:-8rem}.swagger-ui .nl7-l{margin-left:-16rem}.swagger-ui .nr1-l{margin-right:-.25rem}.swagger-ui .nr2-l{margin-right:-.5rem}.swagger-ui .nr3-l{margin-right:-1rem}.swagger-ui .nr4-l{margin-right:-2rem}.swagger-ui .nr5-l{margin-right:-4rem}.swagger-ui .nr6-l{margin-right:-8rem}.swagger-ui .nr7-l{margin-right:-16rem}.swagger-ui .nb1-l{margin-bottom:-.25rem}.swagger-ui .nb2-l{margin-bottom:-.5rem}.swagger-ui .nb3-l{margin-bottom:-1rem}.swagger-ui .nb4-l{margin-bottom:-2rem}.swagger-ui .nb5-l{margin-bottom:-4rem}.swagger-ui .nb6-l{margin-bottom:-8rem}.swagger-ui .nb7-l{margin-bottom:-16rem}.swagger-ui .nt1-l{margin-top:-.25rem}.swagger-ui .nt2-l{margin-top:-.5rem}.swagger-ui .nt3-l{margin-top:-1rem}.swagger-ui .nt4-l{margin-top:-2rem}.swagger-ui .nt5-l{margin-top:-4rem}.swagger-ui .nt6-l{margin-top:-8rem}.swagger-ui .nt7-l{margin-top:-16rem}}.swagger-ui .collapse{border-collapse:collapse;border-spacing:0}.swagger-ui .striped--light-silver:nth-child(odd){background-color:#aaa}.swagger-ui .striped--moon-gray:nth-child(odd){background-color:#ccc}.swagger-ui .striped--light-gray:nth-child(odd){background-color:#eee}.swagger-ui .striped--near-white:nth-child(odd){background-color:#f4f4f4}.swagger-ui .stripe-light:nth-child(odd){background-color:hsla(0,0%,100%,.1)}.swagger-ui .stripe-dark:nth-child(odd){background-color:rgba(0,0,0,.1)}.swagger-ui .strike{text-decoration:line-through}.swagger-ui .underline{text-decoration:underline}.swagger-ui .no-underline{text-decoration:none}@media screen and (min-width:30em){.swagger-ui .strike-ns{text-decoration:line-through}.swagger-ui .underline-ns{text-decoration:underline}.swagger-ui .no-underline-ns{text-decoration:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .strike-m{text-decoration:line-through}.swagger-ui .underline-m{text-decoration:underline}.swagger-ui .no-underline-m{text-decoration:none}}@media screen and (min-width:60em){.swagger-ui .strike-l{text-decoration:line-through}.swagger-ui .underline-l{text-decoration:underline}.swagger-ui .no-underline-l{text-decoration:none}}.swagger-ui .tl{text-align:left}.swagger-ui .tr{text-align:right}.swagger-ui .tc{text-align:center}.swagger-ui .tj{text-align:justify}@media screen and (min-width:30em){.swagger-ui .tl-ns{text-align:left}.swagger-ui .tr-ns{text-align:right}.swagger-ui .tc-ns{text-align:center}.swagger-ui .tj-ns{text-align:justify}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .tl-m{text-align:left}.swagger-ui .tr-m{text-align:right}.swagger-ui .tc-m{text-align:center}.swagger-ui .tj-m{text-align:justify}}@media screen and (min-width:60em){.swagger-ui .tl-l{text-align:left}.swagger-ui .tr-l{text-align:right}.swagger-ui .tc-l{text-align:center}.swagger-ui .tj-l{text-align:justify}}.swagger-ui .ttc{text-transform:capitalize}.swagger-ui .ttl{text-transform:lowercase}.swagger-ui .ttu{text-transform:uppercase}.swagger-ui .ttn{text-transform:none}@media screen and (min-width:30em){.swagger-ui .ttc-ns{text-transform:capitalize}.swagger-ui .ttl-ns{text-transform:lowercase}.swagger-ui .ttu-ns{text-transform:uppercase}.swagger-ui .ttn-ns{text-transform:none}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .ttc-m{text-transform:capitalize}.swagger-ui .ttl-m{text-transform:lowercase}.swagger-ui .ttu-m{text-transform:uppercase}.swagger-ui .ttn-m{text-transform:none}}@media screen and (min-width:60em){.swagger-ui .ttc-l{text-transform:capitalize}.swagger-ui .ttl-l{text-transform:lowercase}.swagger-ui .ttu-l{text-transform:uppercase}.swagger-ui .ttn-l{text-transform:none}}.swagger-ui .f-6,.swagger-ui .f-headline{font-size:6rem}.swagger-ui .f-5,.swagger-ui .f-subheadline{font-size:5rem}.swagger-ui .f1{font-size:3rem}.swagger-ui .f2{font-size:2.25rem}.swagger-ui .f3{font-size:1.5rem}.swagger-ui .f4{font-size:1.25rem}.swagger-ui .f5{font-size:1rem}.swagger-ui .f6{font-size:.875rem}.swagger-ui .f7{font-size:.75rem}@media screen and (min-width:30em){.swagger-ui .f-6-ns,.swagger-ui .f-headline-ns{font-size:6rem}.swagger-ui .f-5-ns,.swagger-ui .f-subheadline-ns{font-size:5rem}.swagger-ui .f1-ns{font-size:3rem}.swagger-ui .f2-ns{font-size:2.25rem}.swagger-ui .f3-ns{font-size:1.5rem}.swagger-ui .f4-ns{font-size:1.25rem}.swagger-ui .f5-ns{font-size:1rem}.swagger-ui .f6-ns{font-size:.875rem}.swagger-ui .f7-ns{font-size:.75rem}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .f-6-m,.swagger-ui .f-headline-m{font-size:6rem}.swagger-ui .f-5-m,.swagger-ui .f-subheadline-m{font-size:5rem}.swagger-ui .f1-m{font-size:3rem}.swagger-ui .f2-m{font-size:2.25rem}.swagger-ui .f3-m{font-size:1.5rem}.swagger-ui .f4-m{font-size:1.25rem}.swagger-ui .f5-m{font-size:1rem}.swagger-ui .f6-m{font-size:.875rem}.swagger-ui .f7-m{font-size:.75rem}}@media screen and (min-width:60em){.swagger-ui .f-6-l,.swagger-ui .f-headline-l{font-size:6rem}.swagger-ui .f-5-l,.swagger-ui .f-subheadline-l{font-size:5rem}.swagger-ui .f1-l{font-size:3rem}.swagger-ui .f2-l{font-size:2.25rem}.swagger-ui .f3-l{font-size:1.5rem}.swagger-ui .f4-l{font-size:1.25rem}.swagger-ui .f5-l{font-size:1rem}.swagger-ui .f6-l{font-size:.875rem}.swagger-ui .f7-l{font-size:.75rem}}.swagger-ui .measure{max-width:30em}.swagger-ui .measure-wide{max-width:34em}.swagger-ui .measure-narrow{max-width:20em}.swagger-ui .indent{text-indent:1em;margin-top:0;margin-bottom:0}.swagger-ui .small-caps{font-variant:small-caps}.swagger-ui .truncate{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@media screen and (min-width:30em){.swagger-ui .measure-ns{max-width:30em}.swagger-ui .measure-wide-ns{max-width:34em}.swagger-ui .measure-narrow-ns{max-width:20em}.swagger-ui .indent-ns{text-indent:1em;margin-top:0;margin-bottom:0}.swagger-ui .small-caps-ns{font-variant:small-caps}.swagger-ui .truncate-ns{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .measure-m{max-width:30em}.swagger-ui .measure-wide-m{max-width:34em}.swagger-ui .measure-narrow-m{max-width:20em}.swagger-ui .indent-m{text-indent:1em;margin-top:0;margin-bottom:0}.swagger-ui .small-caps-m{font-variant:small-caps}.swagger-ui .truncate-m{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}@media screen and (min-width:60em){.swagger-ui .measure-l{max-width:30em}.swagger-ui .measure-wide-l{max-width:34em}.swagger-ui .measure-narrow-l{max-width:20em}.swagger-ui .indent-l{text-indent:1em;margin-top:0;margin-bottom:0}.swagger-ui .small-caps-l{font-variant:small-caps}.swagger-ui .truncate-l{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}.swagger-ui .overflow-container{overflow-y:scroll}.swagger-ui .center{margin-right:auto;margin-left:auto}.swagger-ui .mr-auto{margin-right:auto}.swagger-ui .ml-auto{margin-left:auto}@media screen and (min-width:30em){.swagger-ui .center-ns{margin-right:auto;margin-left:auto}.swagger-ui .mr-auto-ns{margin-right:auto}.swagger-ui .ml-auto-ns{margin-left:auto}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .center-m{margin-right:auto;margin-left:auto}.swagger-ui .mr-auto-m{margin-right:auto}.swagger-ui .ml-auto-m{margin-left:auto}}@media screen and (min-width:60em){.swagger-ui .center-l{margin-right:auto;margin-left:auto}.swagger-ui .mr-auto-l{margin-right:auto}.swagger-ui .ml-auto-l{margin-left:auto}}.swagger-ui .clip{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}@media screen and (min-width:30em){.swagger-ui .clip-ns{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .clip-m{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}@media screen and (min-width:60em){.swagger-ui .clip-l{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}.swagger-ui .ws-normal{white-space:normal}.swagger-ui .nowrap{white-space:nowrap}.swagger-ui .pre{white-space:pre}@media screen and (min-width:30em){.swagger-ui .ws-normal-ns{white-space:normal}.swagger-ui .nowrap-ns{white-space:nowrap}.swagger-ui .pre-ns{white-space:pre}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .ws-normal-m{white-space:normal}.swagger-ui .nowrap-m{white-space:nowrap}.swagger-ui .pre-m{white-space:pre}}@media screen and (min-width:60em){.swagger-ui .ws-normal-l{white-space:normal}.swagger-ui .nowrap-l{white-space:nowrap}.swagger-ui .pre-l{white-space:pre}}.swagger-ui .v-base{vertical-align:baseline}.swagger-ui .v-mid{vertical-align:middle}.swagger-ui .v-top{vertical-align:top}.swagger-ui .v-btm{vertical-align:bottom}@media screen and (min-width:30em){.swagger-ui .v-base-ns{vertical-align:baseline}.swagger-ui .v-mid-ns{vertical-align:middle}.swagger-ui .v-top-ns{vertical-align:top}.swagger-ui .v-btm-ns{vertical-align:bottom}}@media screen and (min-width:30em) and (max-width:60em){.swagger-ui .v-base-m{vertical-align:baseline}.swagger-ui .v-mid-m{vertical-align:middle}.swagger-ui .v-top-m{vertical-align:top}.swagger-ui .v-btm-m{vertical-align:bottom}}@media screen and (min-width:60em){.swagger-ui .v-base-l{vertical-align:baseline}.swagger-ui .v-mid-l{vertical-align:middle}.swagger-ui .v-top-l{vertical-align:top}.swagger-ui .v-btm-l{vertical-align:bottom}}.swagger-ui .dim{opacity:1;transition:opacity .15s ease-in}.swagger-ui .dim:focus,.swagger-ui .dim:hover{opacity:.5;transition:opacity .15s ease-in}.swagger-ui .dim:active{opacity:.8;transition:opacity .15s ease-out}.swagger-ui .glow{transition:opacity .15s ease-in}.swagger-ui .glow:focus,.swagger-ui .glow:hover{opacity:1;transition:opacity .15s ease-in}.swagger-ui .hide-child .child{opacity:0;transition:opacity .15s ease-in}.swagger-ui .hide-child:active .child,.swagger-ui .hide-child:focus .child,.swagger-ui .hide-child:hover .child{opacity:1;transition:opacity .15s ease-in}.swagger-ui .underline-hover:focus,.swagger-ui .underline-hover:hover{text-decoration:underline}.swagger-ui .grow{-moz-osx-font-smoothing:grayscale;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateZ(0);transform:translateZ(0);transition:-webkit-transform .25s ease-out;transition:transform .25s ease-out;transition:transform .25s ease-out, -webkit-transform .25s ease-out}.swagger-ui .grow:focus,.swagger-ui .grow:hover{-webkit-transform:scale(1.05);transform:scale(1.05)}.swagger-ui .grow:active{-webkit-transform:scale(.9);transform:scale(.9)}.swagger-ui .grow-large{-moz-osx-font-smoothing:grayscale;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateZ(0);transform:translateZ(0);transition:-webkit-transform .25s ease-in-out;transition:transform .25s ease-in-out;transition:transform .25s ease-in-out, -webkit-transform .25s ease-in-out}.swagger-ui .grow-large:focus,.swagger-ui .grow-large:hover{-webkit-transform:scale(1.2);transform:scale(1.2)}.swagger-ui .grow-large:active{-webkit-transform:scale(.95);transform:scale(.95)}.swagger-ui .pointer:hover{cursor:pointer}.swagger-ui .shadow-hover{cursor:pointer;position:relative;transition:all .5s cubic-bezier(.165,.84,.44,1)}.swagger-ui .shadow-hover:after{content:"";box-shadow:0 0 16px 2px rgba(0,0,0,.2);border-radius:inherit;opacity:0;position:absolute;top:0;left:0;width:100%;height:100%;z-index:-1;transition:opacity .5s cubic-bezier(.165,.84,.44,1)}.swagger-ui .shadow-hover:focus:after,.swagger-ui .shadow-hover:hover:after{opacity:1}.swagger-ui .bg-animate,.swagger-ui .bg-animate:focus,.swagger-ui .bg-animate:hover{transition:background-color .15s ease-in-out}.swagger-ui .z-0{z-index:0}.swagger-ui .z-1{z-index:1}.swagger-ui .z-2{z-index:2}.swagger-ui .z-3{z-index:3}.swagger-ui .z-4{z-index:4}.swagger-ui .z-5{z-index:5}.swagger-ui .z-999{z-index:999}.swagger-ui .z-9999{z-index:9999}.swagger-ui .z-max{z-index:2147483647}.swagger-ui .z-inherit{z-index:inherit}.swagger-ui .z-initial{z-index:auto}.swagger-ui .z-unset{z-index:unset}.swagger-ui .nested-copy-line-height ol,.swagger-ui .nested-copy-line-height p,.swagger-ui .nested-copy-line-height ul{line-height:1.5}.swagger-ui .nested-headline-line-height h1,.swagger-ui .nested-headline-line-height h2,.swagger-ui .nested-headline-line-height h3,.swagger-ui .nested-headline-line-height h4,.swagger-ui .nested-headline-line-height h5,.swagger-ui .nested-headline-line-height h6{line-height:1.25}.swagger-ui .nested-list-reset ol,.swagger-ui .nested-list-reset ul{padding-left:0;margin-left:0;list-style-type:none}.swagger-ui .nested-copy-indent p+p{text-indent:.1em;margin-top:0;margin-bottom:0}.swagger-ui .nested-copy-seperator p+p{margin-top:1.5em}.swagger-ui .nested-img img{width:100%;max-width:100%;display:block}.swagger-ui .nested-links a{color:#357edd;transition:color .15s ease-in}.swagger-ui .nested-links a:focus,.swagger-ui .nested-links a:hover{color:#96ccff;transition:color .15s ease-in}.swagger-ui .wrapper{width:100%;max-width:1460px;margin:0 auto;padding:0 20px;box-sizing:border-box}.swagger-ui .opblock-tag-section{display:flex;flex-direction:column}.swagger-ui .opblock-tag{display:flex;align-items:center;padding:10px 20px 10px 10px;cursor:pointer;transition:all .2s;border-bottom:1px solid rgba(59,65,81,.3)}.swagger-ui .opblock-tag:hover{background:rgba(0,0,0,.02)}.swagger-ui .opblock-tag{font-size:24px;margin:0 0 5px;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock-tag.no-desc span{flex:1}.swagger-ui .opblock-tag svg{transition:all .4s}.swagger-ui .opblock-tag small{font-size:14px;font-weight:400;flex:1;padding:0 10px;font-family:sans-serif;color:#3b4151}.swagger-ui .parameter__type{font-size:12px;padding:5px 0;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui .parameter-controls{margin-top:.75em}.swagger-ui .examples__title{display:block;font-size:1.1em;font-weight:700;margin-bottom:.75em}.swagger-ui .examples__section{margin-top:1.5em}.swagger-ui .examples__section-header{font-weight:700;font-size:.9rem;margin-bottom:.5rem}.swagger-ui .examples-select{margin-bottom:.75em}.swagger-ui .examples-select__section-label{font-weight:700;font-size:.9rem;margin-right:.5rem}.swagger-ui .example__section{margin-top:1.5em}.swagger-ui .example__section-header{font-weight:700;font-size:.9rem;margin-bottom:.5rem}.swagger-ui .view-line-link{position:relative;top:3px;width:20px;margin:0 5px;cursor:pointer;transition:all .5s}.swagger-ui .opblock{margin:0 0 15px;border:1px solid #000;border-radius:4px;box-shadow:0 0 3px rgba(0,0,0,.19)}.swagger-ui .opblock .tab-header{display:flex;flex:1}.swagger-ui .opblock .tab-header .tab-item{padding:0 40px;cursor:pointer}.swagger-ui .opblock .tab-header .tab-item:first-of-type{padding:0 40px 0 0}.swagger-ui .opblock .tab-header .tab-item.active h4 span{position:relative}.swagger-ui .opblock .tab-header .tab-item.active h4 span:after{position:absolute;bottom:-15px;left:50%;width:120%;height:4px;content:"";-webkit-transform:translateX(-50%);transform:translateX(-50%);background:grey}.swagger-ui .opblock.is-open .opblock-summary{border-bottom:1px solid #000}.swagger-ui .opblock .opblock-section-header{display:flex;align-items:center;padding:8px 20px;min-height:50px;background:hsla(0,0%,100%,.8);box-shadow:0 1px 2px rgba(0,0,0,.1)}.swagger-ui .opblock .opblock-section-header>label{font-size:12px;font-weight:700;display:flex;align-items:center;margin:0 0 0 auto;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock .opblock-section-header>label>span{padding:0 10px 0 0}.swagger-ui .opblock .opblock-section-header h4{font-size:14px;flex:1;margin:0;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock .opblock-summary-method{font-size:14px;font-weight:700;min-width:80px;padding:6px 15px;text-align:center;border-radius:3px;background:#000;text-shadow:0 1px 0 rgba(0,0,0,.1);font-family:sans-serif;color:#fff}.swagger-ui .opblock .opblock-summary-operation-id,.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated{font-size:16px;display:flex;align-items:center;word-break:break-word;padding:0 10px;font-family:monospace;font-weight:600;color:#3b4151}@media (max-width:768px){.swagger-ui .opblock .opblock-summary-operation-id,.swagger-ui .opblock .opblock-summary-path,.swagger-ui .opblock .opblock-summary-path__deprecated{font-size:12px}}.swagger-ui .opblock .opblock-summary-path__deprecated{text-decoration:line-through}.swagger-ui .opblock .opblock-summary-operation-id{font-size:14px}.swagger-ui .opblock .opblock-summary-description{font-size:13px;flex:1 1 auto;word-break:break-word;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock .opblock-summary{display:flex;align-items:center;padding:5px;cursor:pointer}.swagger-ui .opblock .opblock-summary .view-line-link{position:relative;top:2px;width:0;margin:0;cursor:pointer;transition:all .5s}.swagger-ui .opblock .opblock-summary:hover .view-line-link{width:18px;margin:0 5px}.swagger-ui .opblock.opblock-post{border-color:#49cc90;background:rgba(73,204,144,.1)}.swagger-ui .opblock.opblock-post .opblock-summary-method{background:#49cc90}.swagger-ui .opblock.opblock-post .opblock-summary{border-color:#49cc90}.swagger-ui .opblock.opblock-post .tab-header .tab-item.active h4 span:after{background:#49cc90}.swagger-ui .opblock.opblock-put{border-color:#fca130;background:rgba(252,161,48,.1)}.swagger-ui .opblock.opblock-put .opblock-summary-method{background:#fca130}.swagger-ui .opblock.opblock-put .opblock-summary{border-color:#fca130}.swagger-ui .opblock.opblock-put .tab-header .tab-item.active h4 span:after{background:#fca130}.swagger-ui .opblock.opblock-delete{border-color:#f93e3e;background:rgba(249,62,62,.1)}.swagger-ui .opblock.opblock-delete .opblock-summary-method{background:#f93e3e}.swagger-ui .opblock.opblock-delete .opblock-summary{border-color:#f93e3e}.swagger-ui .opblock.opblock-delete .tab-header .tab-item.active h4 span:after{background:#f93e3e}.swagger-ui .opblock.opblock-get{border-color:#61affe;background:rgba(97,175,254,.1)}.swagger-ui .opblock.opblock-get .opblock-summary-method{background:#61affe}.swagger-ui .opblock.opblock-get .opblock-summary{border-color:#61affe}.swagger-ui .opblock.opblock-get .tab-header .tab-item.active h4 span:after{background:#61affe}.swagger-ui .opblock.opblock-patch{border-color:#50e3c2;background:rgba(80,227,194,.1)}.swagger-ui .opblock.opblock-patch .opblock-summary-method{background:#50e3c2}.swagger-ui .opblock.opblock-patch .opblock-summary{border-color:#50e3c2}.swagger-ui .opblock.opblock-patch .tab-header .tab-item.active h4 span:after{background:#50e3c2}.swagger-ui .opblock.opblock-head{border-color:#9012fe;background:rgba(144,18,254,.1)}.swagger-ui .opblock.opblock-head .opblock-summary-method{background:#9012fe}.swagger-ui .opblock.opblock-head .opblock-summary{border-color:#9012fe}.swagger-ui .opblock.opblock-head .tab-header .tab-item.active h4 span:after{background:#9012fe}.swagger-ui .opblock.opblock-options{border-color:#0d5aa7;background:rgba(13,90,167,.1)}.swagger-ui .opblock.opblock-options .opblock-summary-method{background:#0d5aa7}.swagger-ui .opblock.opblock-options .opblock-summary{border-color:#0d5aa7}.swagger-ui .opblock.opblock-options .tab-header .tab-item.active h4 span:after{background:#0d5aa7}.swagger-ui .opblock.opblock-deprecated{opacity:.6;border-color:#ebebeb;background:hsla(0,0%,92.2%,.1)}.swagger-ui .opblock.opblock-deprecated .opblock-summary-method{background:#ebebeb}.swagger-ui .opblock.opblock-deprecated .opblock-summary{border-color:#ebebeb}.swagger-ui .opblock.opblock-deprecated .tab-header .tab-item.active h4 span:after{background:#ebebeb}.swagger-ui .opblock .opblock-schemes{padding:8px 20px}.swagger-ui .opblock .opblock-schemes .schemes-title{padding:0 10px 0 0}.swagger-ui .filter .operation-filter-input{width:100%;margin:20px 0;padding:10px;border:2px solid #d8dde7}.swagger-ui .model-example{margin-top:1em}.swagger-ui .tab{display:flex;padding:0;list-style:none}.swagger-ui .tab li{font-size:12px;min-width:60px;padding:0;cursor:pointer;font-family:sans-serif;color:#3b4151}.swagger-ui .tab li:first-of-type{position:relative;padding-left:0;padding-right:12px}.swagger-ui .tab li:first-of-type:after{position:absolute;top:0;right:6px;width:1px;height:100%;content:"";background:rgba(0,0,0,.2)}.swagger-ui .tab li.active{font-weight:700}.swagger-ui .opblock-description-wrapper,.swagger-ui .opblock-external-docs-wrapper,.swagger-ui .opblock-title_normal{font-size:12px;margin:0 0 5px;padding:15px 20px;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock-description-wrapper h4,.swagger-ui .opblock-external-docs-wrapper h4,.swagger-ui .opblock-title_normal h4{font-size:12px;margin:0 0 5px;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock-description-wrapper p,.swagger-ui .opblock-external-docs-wrapper p,.swagger-ui .opblock-title_normal p{font-size:14px;margin:0;font-family:sans-serif;color:#3b4151}.swagger-ui .opblock-external-docs-wrapper h4{padding-left:0}.swagger-ui .execute-wrapper{padding:20px;text-align:right}.swagger-ui .execute-wrapper .btn{width:100%;padding:8px 40px}.swagger-ui .body-param-options{display:flex;flex-direction:column}.swagger-ui .body-param-options .body-param-edit{padding:10px 0}.swagger-ui .body-param-options label{padding:8px 0}.swagger-ui .body-param-options label select{margin:3px 0 0}.swagger-ui .responses-inner{padding:20px}.swagger-ui .responses-inner h4,.swagger-ui .responses-inner h5{font-size:12px;margin:10px 0 5px;font-family:sans-serif;color:#3b4151}.swagger-ui .response-col_status{font-size:14px;font-family:sans-serif;color:#3b4151}.swagger-ui .response-col_status .response-undocumented{font-size:11px;font-family:monospace;font-weight:600;color:#909090}.swagger-ui .response-col_links{padding-left:2em;max-width:40em;font-size:14px;font-family:sans-serif;color:#3b4151}.swagger-ui .response-col_links .response-undocumented{font-size:11px;font-family:monospace;font-weight:600;color:#909090}.swagger-ui .opblock-body .opblock-loading-animation{display:block;margin:3em auto}.swagger-ui .opblock-body pre.microlight{font-size:12px;margin:0;padding:10px;white-space:pre-wrap;word-wrap:break-word;word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;border-radius:4px;background:#41444e;overflow-wrap:break-word;font-family:monospace;font-weight:600;color:#fff}.swagger-ui .opblock-body pre.microlight span{color:#fff!important}.swagger-ui .opblock-body pre.microlight .headerline{display:block}.swagger-ui .highlight-code{position:relative}.swagger-ui .highlight-code>.microlight{overflow-y:auto;max-height:400px;min-height:6em}.swagger-ui .download-contents{position:absolute;bottom:10px;right:10px;cursor:pointer;background:#7d8293;text-align:center;padding:5px;border-radius:4px;font-family:sans-serif;font-weight:600;color:#fff;font-size:14px;height:30px;width:75px}.swagger-ui .scheme-container{margin:0 0 20px;padding:30px 0;background:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,.15)}.swagger-ui .scheme-container .schemes{display:flex;align-items:flex-end}.swagger-ui .scheme-container .schemes>label{font-size:12px;font-weight:700;display:flex;flex-direction:column;margin:-20px 15px 0 0;font-family:sans-serif;color:#3b4151}.swagger-ui .scheme-container .schemes>label select{min-width:130px;text-transform:uppercase}.swagger-ui .loading-container{padding:40px 0 60px;margin-top:1em;min-height:1px;display:flex;justify-content:center;align-items:center;flex-direction:column}.swagger-ui .loading-container .loading{position:relative}.swagger-ui .loading-container .loading:after{font-size:10px;font-weight:700;position:absolute;top:50%;left:50%;content:"loading";-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);text-transform:uppercase;font-family:sans-serif;color:#3b4151}.swagger-ui .loading-container .loading:before{position:absolute;top:50%;left:50%;display:block;width:60px;height:60px;margin:-30px;content:"";-webkit-animation:rotation 1s linear infinite,opacity .5s;animation:rotation 1s linear infinite,opacity .5s;opacity:1;border:2px solid rgba(85,85,85,.1);border-top-color:rgba(0,0,0,.6);border-radius:100%;-webkit-backface-visibility:hidden;backface-visibility:hidden}@-webkit-keyframes rotation{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes rotation{to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.swagger-ui .response-controls{padding-top:1em;display:flex}.swagger-ui .response-control-media-type{margin-right:1em}.swagger-ui .response-control-media-type--accept-controller select{border-color:green}.swagger-ui .response-control-media-type__accept-message{color:green;font-size:.7em}.swagger-ui .response-control-examples__title,.swagger-ui .response-control-media-type__title{display:block;margin-bottom:.2em;font-size:.7em}@-webkit-keyframes blinker{50%{opacity:0}}@keyframes blinker{50%{opacity:0}}.swagger-ui section h3{font-family:sans-serif;color:#3b4151}.swagger-ui a.nostyle{display:inline}.swagger-ui a.nostyle,.swagger-ui a.nostyle:visited{text-decoration:inherit;color:inherit;cursor:pointer}.swagger-ui .version-pragma{height:100%;padding:5em 0}.swagger-ui .version-pragma__message{display:flex;justify-content:center;height:100%;font-size:1.2em;text-align:center;line-height:1.5em;padding:0 .6em}.swagger-ui .version-pragma__message>div{max-width:55ch;flex:1}.swagger-ui .version-pragma__message code{background-color:#dedede;padding:4px 4px 2px;white-space:pre}.swagger-ui .btn{font-size:14px;font-weight:700;padding:5px 23px;transition:all .3s;border:2px solid grey;border-radius:4px;background:transparent;box-shadow:0 1px 2px rgba(0,0,0,.1);font-family:sans-serif;color:#3b4151}.swagger-ui .btn.btn-sm{font-size:12px;padding:4px 23px}.swagger-ui .btn[disabled]{cursor:not-allowed;opacity:.3}.swagger-ui .btn:hover{box-shadow:0 0 5px rgba(0,0,0,.3)}.swagger-ui .btn.cancel{border-color:#ff6060;background-color:transparent;font-family:sans-serif;color:#ff6060}.swagger-ui .btn.authorize{line-height:1;display:inline;color:#49cc90;border-color:#49cc90;background-color:transparent}.swagger-ui .btn.authorize span{float:left;padding:4px 20px 0 0}.swagger-ui .btn.authorize svg{fill:#49cc90}.swagger-ui .btn.execute{background-color:#4990e2;color:#fff;border-color:#4990e2}.swagger-ui .btn-group{display:flex;padding:30px}.swagger-ui .btn-group .btn{flex:1}.swagger-ui .btn-group .btn:first-child{border-radius:4px 0 0 4px}.swagger-ui .btn-group .btn:last-child{border-radius:0 4px 4px 0}.swagger-ui .authorization__btn{padding:0 10px;border:none;background:none}.swagger-ui .authorization__btn.locked{opacity:1}.swagger-ui .authorization__btn.unlocked{opacity:.4}.swagger-ui .expand-methods,.swagger-ui .expand-operation{border:none;background:none}.swagger-ui .expand-methods svg,.swagger-ui .expand-operation svg{width:20px;height:20px}.swagger-ui .expand-methods{padding:0 10px}.swagger-ui .expand-methods:hover svg{fill:#404040}.swagger-ui .expand-methods svg{transition:all .3s;fill:#707070}.swagger-ui button{cursor:pointer;outline:none}.swagger-ui button.invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;border-color:#f93e3e;background:#feebeb}.swagger-ui select{font-size:14px;font-weight:700;padding:5px 40px 5px 10px;border:2px solid #41444e;border-radius:4px;background:#f7f7f7 url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+PHBhdGggZD0iTTEzLjQxOCA3Ljg1OWEuNjk1LjY5NSAwIDAxLjk3OCAwIC42OC42OCAwIDAxMCAuOTY5bC0zLjkwOCAzLjgzYS42OTcuNjk3IDAgMDEtLjk3OSAwbC0zLjkwOC0zLjgzYS42OC42OCAwIDAxMC0uOTY5LjY5NS42OTUgMCAwMS45NzggMEwxMCAxMWwzLjQxOC0zLjE0MXoiLz48L3N2Zz4=) right 10px center no-repeat;background-size:20px;box-shadow:0 1px 2px 0 rgba(0,0,0,.25);font-family:sans-serif;color:#3b4151;-webkit-appearance:none;-moz-appearance:none;appearance:none}.swagger-ui select[multiple]{margin:5px 0;padding:5px;background:#f7f7f7}.swagger-ui select.invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;border-color:#f93e3e;background:#feebeb}.swagger-ui .opblock-body select{min-width:230px}@media (max-width:768px){.swagger-ui .opblock-body select{min-width:180px}}.swagger-ui label{font-size:12px;font-weight:700;margin:0 0 5px;font-family:sans-serif;color:#3b4151}.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text],.swagger-ui textarea{min-width:100px;margin:5px 0;padding:8px 10px;border:1px solid #d9d9d9;border-radius:4px;background:#fff}@media (max-width:768px){.swagger-ui input[type=email],.swagger-ui input[type=file],.swagger-ui input[type=password],.swagger-ui input[type=search],.swagger-ui input[type=text],.swagger-ui textarea{max-width:175px}}.swagger-ui input[type=email].invalid,.swagger-ui input[type=file].invalid,.swagger-ui input[type=password].invalid,.swagger-ui input[type=search].invalid,.swagger-ui input[type=text].invalid,.swagger-ui textarea.invalid{-webkit-animation:shake .4s 1;animation:shake .4s 1;border-color:#f93e3e;background:#feebeb}.swagger-ui input[disabled],.swagger-ui select[disabled],.swagger-ui textarea[disabled]{background-color:#fafafa;color:#888;cursor:not-allowed}.swagger-ui select[disabled]{border-color:#888}.swagger-ui textarea[disabled]{background-color:#41444e;color:#fff}@-webkit-keyframes shake{10%,90%{-webkit-transform:translate3d(-1px,0,0);transform:translate3d(-1px,0,0)}20%,80%{-webkit-transform:translate3d(2px,0,0);transform:translate3d(2px,0,0)}30%,50%,70%{-webkit-transform:translate3d(-4px,0,0);transform:translate3d(-4px,0,0)}40%,60%{-webkit-transform:translate3d(4px,0,0);transform:translate3d(4px,0,0)}}@keyframes shake{10%,90%{-webkit-transform:translate3d(-1px,0,0);transform:translate3d(-1px,0,0)}20%,80%{-webkit-transform:translate3d(2px,0,0);transform:translate3d(2px,0,0)}30%,50%,70%{-webkit-transform:translate3d(-4px,0,0);transform:translate3d(-4px,0,0)}40%,60%{-webkit-transform:translate3d(4px,0,0);transform:translate3d(4px,0,0)}}.swagger-ui textarea{font-size:12px;width:100%;min-height:280px;padding:10px;border:none;border-radius:4px;outline:none;background:hsla(0,0%,100%,.8);font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui textarea:focus{border:2px solid #61affe}.swagger-ui textarea.curl{font-size:12px;min-height:100px;margin:0;padding:10px;resize:none;border-radius:4px;background:#41444e;font-family:monospace;font-weight:600;color:#fff}.swagger-ui .checkbox{padding:5px 0 10px;transition:opacity .5s;color:#303030}.swagger-ui .checkbox label{display:flex}.swagger-ui .checkbox p{font-weight:400!important;font-style:italic;margin:0!important;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui .checkbox input[type=checkbox]{display:none}.swagger-ui .checkbox input[type=checkbox]+label>.item{position:relative;top:3px;display:inline-block;width:16px;height:16px;margin:0 8px 0 0;padding:5px;cursor:pointer;border-radius:1px;background:#e8e8e8;box-shadow:0 0 0 2px #e8e8e8;flex:none}.swagger-ui .checkbox input[type=checkbox]+label>.item:active{-webkit-transform:scale(.9);transform:scale(.9)}.swagger-ui .checkbox input[type=checkbox]:checked+label>.item{background:#e8e8e8 url("data:image/svg+xml;charset=utf-8,%3Csvg width='10' height='8' viewBox='3 7 10 8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%2341474E' fill-rule='evenodd' d='M6.333 15L3 11.667l1.333-1.334 2 2L11.667 7 13 8.333z'/%3E%3C/svg%3E") 50% no-repeat}.swagger-ui .dialog-ux{position:fixed;z-index:9999;top:0;right:0;bottom:0;left:0}.swagger-ui .dialog-ux .backdrop-ux{position:fixed;top:0;right:0;bottom:0;left:0;background:rgba(0,0,0,.8)}.swagger-ui .dialog-ux .modal-ux{position:absolute;z-index:9999;top:50%;left:50%;width:100%;min-width:300px;max-width:650px;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);border:1px solid #ebebeb;border-radius:4px;background:#fff;box-shadow:0 10px 30px 0 rgba(0,0,0,.2)}.swagger-ui .dialog-ux .modal-ux-content{overflow-y:auto;max-height:540px;padding:20px}.swagger-ui .dialog-ux .modal-ux-content p{font-size:12px;margin:0 0 5px;color:#41444e;font-family:sans-serif;color:#3b4151}.swagger-ui .dialog-ux .modal-ux-content h4{font-size:18px;font-weight:600;margin:15px 0 0;font-family:sans-serif;color:#3b4151}.swagger-ui .dialog-ux .modal-ux-header{display:flex;padding:12px 0;border-bottom:1px solid #ebebeb;align-items:center}.swagger-ui .dialog-ux .modal-ux-header .close-modal{padding:0 10px;border:none;background:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.swagger-ui .dialog-ux .modal-ux-header h3{font-size:20px;font-weight:600;margin:0;padding:0 20px;flex:1;font-family:sans-serif;color:#3b4151}.swagger-ui .model{font-size:12px;font-weight:300;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui .model .deprecated span,.swagger-ui .model .deprecated td{color:#a0a0a0!important}.swagger-ui .model .deprecated>td:first-of-type{text-decoration:line-through}.swagger-ui .model-toggle{font-size:10px;position:relative;top:6px;display:inline-block;margin:auto .3em;cursor:pointer;transition:-webkit-transform .15s ease-in;transition:transform .15s ease-in;transition:transform .15s ease-in, -webkit-transform .15s ease-in;-webkit-transform:rotate(90deg);transform:rotate(90deg);-webkit-transform-origin:50% 50%;transform-origin:50% 50%}.swagger-ui .model-toggle.collapsed{-webkit-transform:rotate(0deg);transform:rotate(0deg)}.swagger-ui .model-toggle:after{display:block;width:20px;height:20px;content:"";background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath d='M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z'/%3E%3C/svg%3E") 50% no-repeat;background-size:100%}.swagger-ui .model-jump-to-path{position:relative;cursor:pointer}.swagger-ui .model-jump-to-path .view-line-link{position:absolute;top:-.4em;cursor:pointer}.swagger-ui .model-title{position:relative}.swagger-ui .model-title:hover .model-hint{visibility:visible}.swagger-ui .model-hint{position:absolute;top:-1.8em;visibility:hidden;padding:.1em .5em;white-space:nowrap;color:#ebebeb;border-radius:4px;background:rgba(0,0,0,.7)}.swagger-ui .model p{margin:0 0 1em}.swagger-ui section.models{margin:30px 0;border:1px solid rgba(59,65,81,.3);border-radius:4px}.swagger-ui section.models.is-open{padding:0 0 20px}.swagger-ui section.models.is-open h4{margin:0 0 5px;border-bottom:1px solid rgba(59,65,81,.3)}.swagger-ui section.models h4{font-size:16px;display:flex;align-items:center;margin:0;padding:10px 20px 10px 10px;cursor:pointer;transition:all .2s;font-family:sans-serif;color:#606060}.swagger-ui section.models h4 svg{transition:all .4s}.swagger-ui section.models h4 span{flex:1}.swagger-ui section.models h4:hover{background:rgba(0,0,0,.02)}.swagger-ui section.models h5{font-size:16px;margin:0 0 10px;font-family:sans-serif;color:#707070}.swagger-ui section.models .model-jump-to-path{position:relative;top:5px}.swagger-ui section.models .model-container{margin:0 20px 15px;position:relative;transition:all .5s;border-radius:4px;background:rgba(0,0,0,.05)}.swagger-ui section.models .model-container:hover{background:rgba(0,0,0,.07)}.swagger-ui section.models .model-container:first-of-type{margin:20px}.swagger-ui section.models .model-container:last-of-type{margin:0 20px}.swagger-ui section.models .model-container .models-jump-to-path{position:absolute;top:8px;right:5px;opacity:.65}.swagger-ui section.models .model-box{background:none}.swagger-ui .model-box{padding:10px;display:inline-block;border-radius:4px;background:rgba(0,0,0,.1)}.swagger-ui .model-box .model-jump-to-path{position:relative;top:4px}.swagger-ui .model-box.deprecated{opacity:.5}.swagger-ui .model-title{font-size:16px;font-family:sans-serif;color:#505050}.swagger-ui .model-deprecated-warning{font-size:16px;font-weight:600;margin-right:1em;font-family:sans-serif;color:#f93e3e}.swagger-ui span>span.model .brace-close{padding:0 0 0 10px}.swagger-ui .prop-name{display:inline-block;margin-right:1em}.swagger-ui .prop-type{color:#55a}.swagger-ui .prop-enum{display:block}.swagger-ui .prop-format{color:#606060}.swagger-ui .servers>label{font-size:12px;margin:-20px 15px 0 0;font-family:sans-serif;color:#3b4151}.swagger-ui .servers>label select{min-width:130px;max-width:100%}.swagger-ui .servers h4.message{padding-bottom:2em}.swagger-ui .servers table tr{width:30em}.swagger-ui .servers table td{display:inline-block;max-width:15em;vertical-align:middle;padding-top:10px;padding-bottom:10px}.swagger-ui .servers table td:first-of-type{padding-right:2em}.swagger-ui .servers table td input{width:100%;height:100%}.swagger-ui .servers .computed-url{margin:2em 0}.swagger-ui .servers .computed-url code{display:inline-block;padding:4px;font-size:16px;margin:0 1em}.swagger-ui .servers-title{font-size:12px;font-weight:700}.swagger-ui .operation-servers h4.message{margin-bottom:2em}.swagger-ui table{width:100%;padding:0 10px;border-collapse:collapse}.swagger-ui table.model tbody tr td{padding:0;vertical-align:top}.swagger-ui table.model tbody tr td:first-of-type{width:174px;padding:0 0 0 2em}.swagger-ui table.headers td{font-size:12px;font-weight:300;vertical-align:middle;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui table tbody tr td{padding:10px 0 0;vertical-align:top}.swagger-ui table tbody tr td:first-of-type{max-width:20%;min-width:6em;padding:10px 0}.swagger-ui table thead tr td,.swagger-ui table thead tr th{font-size:12px;font-weight:700;padding:12px 0;text-align:left;border-bottom:1px solid rgba(59,65,81,.2);font-family:sans-serif;color:#3b4151}.swagger-ui .parameters-col_description{width:99%;margin-bottom:2em}.swagger-ui .parameters-col_description input[type=text]{width:100%;max-width:340px}.swagger-ui .parameters-col_description select{border-width:1px}.swagger-ui .parameter__name{font-size:16px;font-weight:400;margin-right:.75em;font-family:sans-serif;color:#3b4151}.swagger-ui .parameter__name.required{font-weight:700}.swagger-ui .parameter__name.required:after{font-size:10px;position:relative;top:-6px;padding:5px;content:"required";color:rgba(255,0,0,.6)}.swagger-ui .parameter__extension,.swagger-ui .parameter__in{font-size:12px;font-style:italic;font-family:monospace;font-weight:600;color:grey}.swagger-ui .parameter__deprecated{font-size:12px;font-style:italic;font-family:monospace;font-weight:600;color:red}.swagger-ui .parameter__empty_value_toggle{font-size:13px;padding-top:5px;padding-bottom:12px}.swagger-ui .parameter__empty_value_toggle input{margin-right:7px}.swagger-ui .parameter__empty_value_toggle.disabled{opacity:.7}.swagger-ui .table-container{padding:20px}.swagger-ui .response-col_description{width:99%}.swagger-ui .response-col_links{min-width:6em}.swagger-ui .topbar{padding:10px 0;background-color:#1b1b1b}.swagger-ui .topbar .topbar-wrapper,.swagger-ui .topbar a{display:flex;align-items:center}.swagger-ui .topbar a{font-size:1.5em;font-weight:700;flex:1;max-width:300px;text-decoration:none;font-family:sans-serif;color:#fff}.swagger-ui .topbar a span{margin:0;padding:0 10px}.swagger-ui .topbar .download-url-wrapper{display:flex;flex:3;justify-content:flex-end}.swagger-ui .topbar .download-url-wrapper input[type=text]{width:100%;margin:0;border:2px solid #62a03f;border-radius:4px 0 0 4px;outline:none}.swagger-ui .topbar .download-url-wrapper .select-label{display:flex;align-items:center;width:100%;max-width:600px;margin:0;color:#f0f0f0}.swagger-ui .topbar .download-url-wrapper .select-label span{font-size:16px;flex:1;padding:0 10px 0 0;text-align:right}.swagger-ui .topbar .download-url-wrapper .select-label select{flex:2;width:100%;border:2px solid #62a03f;outline:none;box-shadow:none}.swagger-ui .topbar .download-url-wrapper .download-url-button{font-size:16px;font-weight:700;padding:4px 30px;border:none;border-radius:0 4px 4px 0;background:#62a03f;font-family:sans-serif;color:#fff}.swagger-ui .info{margin:50px 0}.swagger-ui .info hgroup.main{margin:0 0 20px}.swagger-ui .info hgroup.main a{font-size:12px}.swagger-ui .info pre{font-size:14px}.swagger-ui .info li,.swagger-ui .info p,.swagger-ui .info table{font-size:14px;font-family:sans-serif;color:#3b4151}.swagger-ui .info h1,.swagger-ui .info h2,.swagger-ui .info h3,.swagger-ui .info h4,.swagger-ui .info h5{font-family:sans-serif;color:#3b4151}.swagger-ui .info a{font-size:14px;transition:all .4s;font-family:sans-serif;color:#4990e2}.swagger-ui .info a:hover{color:#1f69c0}.swagger-ui .info>div{margin:0 0 5px}.swagger-ui .info .base-url{font-size:12px;font-weight:300!important;margin:0;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui .info .title{font-size:36px;margin:0;font-family:sans-serif;color:#3b4151}.swagger-ui .info .title small{font-size:10px;position:relative;top:-5px;display:inline-block;margin:0 0 0 5px;padding:2px 4px;vertical-align:super;border-radius:57px;background:#7d8492}.swagger-ui .info .title small pre{margin:0;padding:0;font-family:sans-serif;color:#fff}.swagger-ui .auth-btn-wrapper{display:flex;padding:10px 0;justify-content:center}.swagger-ui .auth-btn-wrapper .btn-done{margin-right:1em}.swagger-ui .auth-wrapper{display:flex;flex:1;justify-content:flex-end}.swagger-ui .auth-wrapper .authorize{padding-right:20px;margin-right:10px}.swagger-ui .auth-container{margin:0 0 10px;padding:10px 20px;border-bottom:1px solid #ebebeb}.swagger-ui .auth-container:last-of-type{margin:0;padding:10px 20px;border:0}.swagger-ui .auth-container h4{margin:5px 0 15px!important}.swagger-ui .auth-container .wrapper{margin:0;padding:0}.swagger-ui .auth-container input[type=password],.swagger-ui .auth-container input[type=text]{min-width:230px}.swagger-ui .auth-container .errors{font-size:12px;padding:10px;border-radius:4px;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui .scopes h2{font-size:14px;font-family:sans-serif;color:#3b4151}.swagger-ui .scope-def{padding:0 0 20px}.swagger-ui .errors-wrapper{margin:20px;padding:10px 20px;-webkit-animation:scaleUp .5s;animation:scaleUp .5s;border:2px solid #f93e3e;border-radius:4px;background:rgba(249,62,62,.1)}.swagger-ui .errors-wrapper .error-wrapper{margin:0 0 10px}.swagger-ui .errors-wrapper .errors h4{font-size:14px;margin:0;font-family:monospace;font-weight:600;color:#3b4151}.swagger-ui .errors-wrapper .errors small{color:#606060}.swagger-ui .errors-wrapper hgroup{display:flex;align-items:center}.swagger-ui .errors-wrapper hgroup h4{font-size:20px;margin:0;flex:1;font-family:sans-serif;color:#3b4151}@-webkit-keyframes scaleUp{0%{-webkit-transform:scale(.8);transform:scale(.8);opacity:0}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes scaleUp{0%{-webkit-transform:scale(.8);transform:scale(.8);opacity:0}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}.swagger-ui .Resizer.vertical.disabled{display:none}.swagger-ui .markdown p,.swagger-ui .markdown pre,.swagger-ui .renderedMarkdown p,.swagger-ui .renderedMarkdown pre{margin:1em auto}.swagger-ui .markdown pre,.swagger-ui .renderedMarkdown pre{color:#000;font-weight:400;white-space:pre-wrap;background:none;padding:0}.swagger-ui .markdown code,.swagger-ui .renderedMarkdown code{font-size:14px;padding:5px 7px;border-radius:4px;background:rgba(0,0,0,.05);font-family:monospace;font-weight:600;color:#9012fe}.swagger-ui .markdown pre>code,.swagger-ui .renderedMarkdown pre>code{display:block} + +/*# sourceMappingURL=swagger-ui.css.map*/ \ No newline at end of file diff --git a/docs/concepts/index.html b/docs/concepts/index.html new file mode 100644 index 00000000..9beaeb9d --- /dev/null +++ b/docs/concepts/index.html @@ -0,0 +1,503 @@ + + + + + + + + + + + + + + + + + + + + + +Concepts | Luet + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Concepts

+
Documentation references
+ + +
+ + + + + + + + +
+ + +
+
+ Overview +
+

See Luet in action.

+
+ + +
+
+ Packages +
+

Package definition syntax

+
+ + +
+
+ Plugins and Extensions +
+

Extend luet with plugins and extensions

+
+ + +
+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/concepts/index.xml b/docs/concepts/index.xml new file mode 100644 index 00000000..989c1b1f --- /dev/null +++ b/docs/concepts/index.xml @@ -0,0 +1,316 @@ + + + Luet – Concepts + https://luet-lab.github.io/docs/docs/concepts/ + Recent content in Concepts on Luet + Hugo -- gohugo.io + + + + + + + + + + + Docs: Overview + https://luet-lab.github.io/docs/docs/concepts/overview/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/overview/ + + + + <p>Luet provides an abstraction layer on top of the container image layer to make the package a first class construct. A package definition and all its dependencies are translated by Luet to Dockerfiles which can then be built anywhere that docker runs.</p> +<p>Luet is written entirely in Go and comes as a single static binary. This has a few advantages:</p> +<ul> +<li>Easy to recover. You can use luet to bootstrap the system entirely from the ground-up.</li> +<li>Package manager has no dependencies on the packages that it installs. There is no chance of breaking the package manager by installing a conflicting package, or uninstalling one.</li> +<li>Portable - it can run on any architecture</li> +</ul> +<p>Luet brings the containers ecosystem to standard software package management and delivery. It is fully built around the container concept, and leverages the huge catalog already present in the wild. It lets you use Docker images from <a href="https://hub.docker.com/">Docker Hub</a>, or from private registries to build packages, and helps you to redistribute them.</p> +<p>Systems that are using luet as a package manager can consume Luet repositories with only luet itself. No dependency is required by the Package manager, giving you the full control on what you install or not in the system. It can be used to generate <em>Linux from Scratch</em> distributions, also to build Docker images, or to simply build standalone packages that you might want to redistribute.</p> +<p>The syntax proposed aims to be <a href="https://en.wikipedia.org/wiki/KISS_principle">KISS</a> - you define a set of steps that need to be run to build your image, and a set of constraints denoting the requirements or conflicts of your package.</p> +<h2 id="why-another-package-manager">Why another Package manager?</h2> +<p>There is no known package manager with 0-dependency that fully leverages the container ecosystem. This gap forces current package managers to depend on a specific system layout as base of the building process and the corresponding depencies. This can cause situations leading to a broken system. We want to fix that by empowering the user, by building their own packages, and redistribute them. +Luet allows also to create packages entirely from Docker images content. In this way the user can actually bundle all the files of an image into a package and deliver part of it, or entirely as a layer. All of that, without the package manager depending on a single bit from it.</p> +<h2 id="package-definitions">Package definitions</h2> +<p>Luet uses <a href="https://en.wikipedia.org/wiki/YAML">YAML</a> for the package specification format, Luet parses the <a href="https://luet-lab.github.io/docs/docs/docs/concepts/overview/constraints">requirements</a> to build <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages">packages</a>, so Luet can consume them.</p> +<p>Below you can find links to tutorials on how to build packages, images and repositories.</p> + + + + + + Docs: Packages + https://luet-lab.github.io/docs/docs/concepts/packages/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/packages/ + + + + <p>A Package in Luet is denoted by a triple (<code>name</code>, <code>category</code> and <code>version</code>), here called <em>package form</em> in a <code>definition.yaml</code> file in YAML:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;awesome&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>While <code>category</code> and <code>version</code> can be omitted, the name is required. Note that when refering to a package, the triplet is always present:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;awesome&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h2 id="building-process">Building process</h2> +<p>When a package is required to be built, Luet resolves the dependency trees and orders the spec files to satisfy the given contraints.</p> +<p>Each package build context is where the spec files are found (<code>definition.yaml</code> and <code>build.yaml</code>). This means that in the container, which is running the build process, the resources inside the package folder are accessible, as normally in Docker.</p> +<pre tabindex="0"><code>❯ tree distro/raspbian/buster +distro/raspbian/buster +├── build.sh +├── build.yaml +├── definition.yaml +└── finalize.yaml +</code></pre><p>In the example above, <code>build.sh</code> is accessible in build time and can be invoked easily in build time in <code>build.yaml</code>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">sh build.sh</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h2 id="package-provides">Package provides</h2> +<p>Packages can specify a list of <code>provides</code>. This is a list of packages in <em>package form</em>, which indicates that the current definition <em>replaces</em> every occurrence of the packages in the list (both at <em>build</em> and <em>runtime</em>). This mechanism is particularly helpful for handling package moves or for enabling virtual packages (e.g., <a href="https://packages.gentoo.org/categories/virtual">gentoo virtual packages</a>).</p> +<p><em>Note: packages in the <code>provides</code> list don&rsquo;t need to exist or have a valid build definition either.</em></p> +<h2 id="package-types">Package types</h2> +<p>By a combination of keywords in <code>build.yaml</code>, you end up with categories of packages that can be built:</p> +<ul> +<li>Seed packages</li> +<li>Packages deltas</li> +<li>Package layers</li> +<li>Package with includes</li> +</ul> +<p>Check the <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile">Specfile concept</a> page for a full overview of the available keywords in the Luet specfile format.</p> +<h3 id="seed-packages">Seed packages</h3> +<p>Seed packages denote a parent package (or root) that can be used by other packages as a dependency. Normally, seed packages include just an image (preferably tagged) used as a base for other packages to depend on.</p> +<p>It is useful to pin to specific image versions, and to write down in a tree where packages are coming from. There can be as many seed packages as you like in a tree.</p> +<p>A seed package <code>build.yaml</code> example is the following:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine:3.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>Every other package that depends on it will inherit the layers from it.</p> +<p>If you want to extract the content of the seed package in a separate packages (splitting), you can just create as many package as you wish depending on that one, and extract its content, for example:</p> +<p><strong>alpine/build.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine:3.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><strong>alpine/definition.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;3.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;seed&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><strong>sh/build.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#8f5902;font-style:italic"># List of build-time dependencies</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;3.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;seed&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">unpack</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># Tells luet to use the image content by unpacking it</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">includes</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/bin/sh</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><strong>sh/definition.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;sh&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;utils&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>In this example, there are two packages being specified:</p> +<ul> +<li>One is the <code>seed</code> package, which is the base image employed to later extract packages. It has no installable content, and it is just virtually used during build phase.</li> +<li><code>sh</code> is the package which contains <code>/bin/sh</code>, extracted from the seed image and packaged. This can be consumed by Luet clients in order to install <code>sh</code> in their system.</li> +</ul> +<h3 id="packages-delta">Packages delta</h3> +<p>Luet, by default, will try to calculate the delta of the package that is meant to be built. This means that it tracks <strong>incrementally</strong> the changes in the packages, to ease the build definition. Let&rsquo;s see an example.</p> +<p>Given the root package: +<strong>alpine/build.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine:3.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><strong>alpine/definition.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;3.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;seed&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>We can generate any file, and include it in our package by defining this simple package:</p> +<p><strong>foo/build.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#8f5902;font-style:italic"># List of build-time dependencies</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;3.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;seed&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo &#34;Awesome&#34; &gt; /foo</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><strong>foo/definition.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;utils&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>By analyzing the difference between the two packages, Luet will automatically track and package <code>/foo</code> as part of the <code>foo</code> package.</p> +<p>To allow operations that must not be accounted in to the final package, you can use the <code>prelude</code> keyword:</p> +<p><strong>foo/build.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#8f5902;font-style:italic"># List of build-time dependencies</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;3.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;seed&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">prelude</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo &#34;Not packaged&#34; &gt; /invisible</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo &#34;Awesome&#34; &gt; /foo</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><strong>foo/definition.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;utils&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>The list of commands inside <code>prelude</code> that would produce artifacts, are not accounted to the final package. In this example, only <code>/foo</code> would be packaged (which output is equivalent to the example above).</p> +<p>This can be used, for instance, to fetch sources that must not be part of the package.</p> +<p>You can apply restrictions anytime and use the <code>includes</code> keyword to specifically pin to the files you wish in your package.</p> +<h3 id="package-layers">Package layers</h3> +<p>Luet can be used to track entire layers and make them installable by Luet clients.</p> +<p>Given the examples above:</p> +<p><strong>alpine/build.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine:3.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><strong>alpine/definition.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;3.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;seed&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>An installable package derived by the seed, with the actual full content of the layer can be composed as follows:</p> +<p><strong>foo/build.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#8f5902;font-style:italic"># List of build-time dependencies</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;3.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;seed&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">unpack</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># It advertize Luet to consume the package as is</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><strong>foo/definition.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;utils&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>This can be combined with other keywords to manipulate the resulting package (layer), for example:</p> +<p><strong>foo/build.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#8f5902;font-style:italic"># List of build-time dependencies</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;3.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;seed&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">unpack</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># It advertize Luet to consume the package as is</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">apk update</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">apk add git</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">apk add ..</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><strong>foo/definition.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;utils&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="package-includes">Package includes</h3> +<p>In addition, the <code>includes</code> keyword can be set in order to extract portions from the package image.</p> +<p><strong>git/build.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#8f5902;font-style:italic"># List of build-time dependencies</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;3.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;seed&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">unpack</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#8f5902;font-style:italic"># It advertize Luet to consume the package as is</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">apk update</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">apk add git</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">includes</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/usr/bin/git</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><strong>foo/definition.yaml</strong></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;git&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;utils&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>As a reminder, the <code>includes</code> keywords accepts regular expressions in the Golang format. Any criteria expressed by means of Golang regular expressions, and matching the file name (absolute path), will be part of the final package.</p> + + + + + + Docs: Plugins and Extensions + https://luet-lab.github.io/docs/docs/concepts/plugins-and-extensions/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/plugins-and-extensions/ + + + + <p>Luet can be extended in 2 ways by extensions and plugins.</p> +<h1 id="before-you-begin">Before you begin</h1> +<p>You need to have a working <code>luet</code> binary installed.</p> +<h2 id="extensions">Extensions</h2> +<p>Extensions expand Luet featureset horizontally, so for example, “luet geniso” will allow you to build an iso using luet, without this needing to be part of the luet core.</p> +<p>An Extension is nothing more than a standalone executable file, whose name begins with <code>luet-</code>. To install an extension, simply move its executable file to anywhere on your system <code>PATH</code>.</p> +<p>All the plugins will be accessible to luet as <code>luet pluginname</code></p> +<h3 id="writing-an-extension">Writing an Extension</h3> +<p>You can write an extension in any programming language or script that allows you to write command-line commands.</p> +<p>Executables receive the inherited environment from luet. An extension determines which command path it wishes to implement based on its name. For example, a plugin wanting to provide a new command luet foo, would simply be named luet-foo, and live somewhere in your PATH.</p> +<h4 id="example-extension">Example Extension</h4> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic">#!/bin/bash +</span><span style="color:#8f5902;font-style:italic"></span> +<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#ce5c00;font-weight:bold">[[</span> <span style="color:#4e9a06">&#34;</span><span style="color:#000">$1</span><span style="color:#4e9a06">&#34;</span> <span style="color:#ce5c00;font-weight:bold">==</span> <span style="color:#4e9a06">&#34;help&#34;</span> <span style="color:#ce5c00;font-weight:bold">]]</span> +<span style="color:#204a87;font-weight:bold">then</span> + <span style="color:#204a87">echo</span> <span style="color:#4e9a06">&#34;Extension help&#34;</span> + <span style="color:#204a87">exit</span> <span style="color:#0000cf;font-weight:bold">0</span> +<span style="color:#204a87;font-weight:bold">fi</span> + +<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#ce5c00;font-weight:bold">[[</span> <span style="color:#4e9a06">&#34;</span><span style="color:#000">$1</span><span style="color:#4e9a06">&#34;</span> <span style="color:#ce5c00;font-weight:bold">==</span> <span style="color:#4e9a06">&#34;run&#34;</span> <span style="color:#ce5c00;font-weight:bold">]]</span> +<span style="color:#204a87;font-weight:bold">then</span> + <span style="color:#8f5902;font-style:italic"># do something interesting</span> +<span style="color:#204a87;font-weight:bold">fi</span> + +<span style="color:#204a87">echo</span> <span style="color:#4e9a06">&#34;I am an Extension named luet-foo&#34;</span> + +</code></pre></div><h3 id="using-an-extension">Using an Extension</h3> +<p>To use the above extension, simply make it executable:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ sudo chmod +x ./luet-foo +</code></pre></div><p>and place it anywhere in your PATH:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ sudo mv ./luet-foo /usr/local/bin +</code></pre></div><p>You may now invoke your extension as a luet command:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet foo +I am an Extension named luet-foo +</code></pre></div><p>All args and flags are passed as-is to the executable:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet foo <span style="color:#204a87">help</span> + +Extension <span style="color:#204a87">help</span> +</code></pre></div><h2 id="plugins">Plugins</h2> +<p>Plugins instead are expanding Luet vertically by hooking into internal events. Plugins and Extensions can be written in any language, bash included! Luet uses <a href="https://github.com/mudler/go-pluggable">go-pluggable</a> so it can dispatch events to external binaries.</p> +<p>Similarly to <strong>Extensions</strong>, a <strong>Plugin</strong> is nothing more than a standalone executable file, but without any special prefix. To install a plugin, simply move its executable file to anywhere on your system <code>PATH</code>.</p> +<p>Differently from <strong>Extensions</strong>, they are not available from the <strong>CLI</strong> and cannot be invoked directly by the user, instead they are called by Luet during its lifecycle.</p> +<h3 id="writing-a-plugin">Writing a Plugin</h3> +<p>You can write a plugin in any programming language or script.</p> +<p>The first argument that is passed to a plugin will always be the event that was emitted by Luet in its lifecycle. You can see all the <a href="https://github.com/mudler/luet/blob/master/pkg/bus/events.go">events available here</a>. The second argument, is a <code>JSON</code> encoded payload of the object that Luet is emitting with the event. The object(s) may vary depending on the emitted event.</p> +<p>The output of the plugin (<code>stdout</code>) will be parsed as JSON. Every plugin must return a valid JSON at the end of its execution, or it will be marked as failed and stops <code>luet</code> further execution. <a href="https://github.com/mudler/go-pluggable#plugin-processed-data">See also the go-pluggable README</a>.</p> +<p>The returning payload should be in the following form:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-json" data-lang="json"><span style="color:#000;font-weight:bold">{</span> <span style="color:#204a87;font-weight:bold">&#34;state&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">&#34;data&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;data&#34;</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">&#34;error&#34;</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#4e9a06">&#34;&#34;</span><span style="color:#000;font-weight:bold">}</span> +</code></pre></div><p>By returning a json with the error field not empty, it will make fail the overall execution.</p> +<h4 id="example-plugin">Example Plugin</h4> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic">#!/bin/bash +</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#204a87">echo</span> <span style="color:#4e9a06">&#34;</span><span style="color:#000">$1</span><span style="color:#4e9a06">&#34;</span> &gt;&gt; /tmp/event.txt +<span style="color:#204a87">echo</span> <span style="color:#4e9a06">&#34;</span><span style="color:#000">$2</span><span style="color:#4e9a06">&#34;</span> &gt;&gt; /tmp/payload.txt + +<span style="color:#204a87">echo</span> <span style="color:#4e9a06">&#34;{}&#34;</span> + +</code></pre></div><h3 id="using-a-plugin">Using a plugin</h3> +<p>To use the above plugin, simply make it executable:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ sudo chmod +x ./test-foo +</code></pre></div><p>and place it anywhere in your PATH:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ sudo mv ./test-foo /usr/local/bin +</code></pre></div><p>Now, when running luet, add <code>--plugin test-foo</code>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet --plugin test-foo install -y foopackage + +</code></pre></div><p>And check <code>/tmp/event.txt</code> to see the event fired and <code>/tmp/payload.txt</code> to check the payloads that were emitted by Luet.</p> +<h3 id="concrete-example">Concrete example</h3> +<p>A plugin that prints the images that are being built in <code>/tmp/exec.log</code>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic">#!/bin/bash +</span><span style="color:#8f5902;font-style:italic"></span><span style="color:#204a87">exec</span> &gt;&gt; /tmp/exec.log +<span style="color:#204a87">exec</span> 2&gt;<span style="color:#000;font-weight:bold">&amp;</span><span style="color:#0000cf;font-weight:bold">1</span> +<span style="color:#000">event</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">&#34;</span><span style="color:#000">$1</span><span style="color:#4e9a06">&#34;</span> +<span style="color:#000">payload</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#4e9a06">&#34;</span><span style="color:#000">$2</span><span style="color:#4e9a06">&#34;</span> +<span style="color:#204a87;font-weight:bold">if</span> <span style="color:#ce5c00;font-weight:bold">[</span> <span style="color:#4e9a06">&#34;</span><span style="color:#000">$event</span><span style="color:#4e9a06">&#34;</span> <span style="color:#ce5c00;font-weight:bold">==</span> <span style="color:#4e9a06">&#34;image.post.build&#34;</span> <span style="color:#ce5c00;font-weight:bold">]</span><span style="color:#000;font-weight:bold">;</span> <span style="color:#204a87;font-weight:bold">then</span> + <span style="color:#000">image</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#204a87;font-weight:bold">$(</span><span style="color:#204a87">echo</span> <span style="color:#4e9a06">&#34;</span><span style="color:#000">$payload</span><span style="color:#4e9a06">&#34;</span> <span style="color:#000;font-weight:bold">|</span> jq -r .data <span style="color:#000;font-weight:bold">|</span> jq -r .ImageName <span style="color:#204a87;font-weight:bold">)</span> + <span style="color:#204a87">echo</span> <span style="color:#4e9a06">&#34;{ \&#34;data\&#34;: \&#34;</span><span style="color:#000">$image</span><span style="color:#4e9a06"> built\&#34; }&#34;</span> +<span style="color:#204a87;font-weight:bold">else</span> + <span style="color:#204a87">echo</span> <span style="color:#4e9a06">&#34;{}&#34;</span> +<span style="color:#204a87;font-weight:bold">fi</span> + +</code></pre></div> + + + + + diff --git a/docs/concepts/overview/build_packages/index.html b/docs/concepts/overview/build_packages/index.html new file mode 100644 index 00000000..05d16f83 --- /dev/null +++ b/docs/concepts/overview/build_packages/index.html @@ -0,0 +1,618 @@ + + + + + + + + + + + + + + + + + + + + +Building packages | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Building packages

+
How to build packages with Luet
+ +

Prerequisistes

+

Luet currently supports Docker and Img as backends to build packages. Both of them can be used and switched in runtime with the --backend option, so either one of them must be present in the host system.

+

Docker

+

Docker is the (less) experimental Luet engine supported. Be sure to have Docker installed and the daemon running. The user running luet commands needs the corresponding permissions to run the docker executable, and to connect to a docker daemon. The only feature needed by the daemon is the ability to build images, so it fully supports remote daemon as well (this can be specified with the DOCKER_HOST environment variable, that is respected by luet)

+

Img

+

Luet supports Img. To use it, simply install it in your system, and while running luet build, you can switch the backend by providing it as a parameter: luet build --backend img. For small packages it is particularly powerful, as it doesn’t require any docker daemon running in the host.

+

Building packages on Kubernetes

+

Luet and img can be used together to orchestrate package builds also on kubernetes. There is available an experimental Kubernetes CRD for Luet which allows to build packages seamelessly in Kubernetes and push package artifacts to an S3 Compatible object storage (e.g. Minio).

+

Building packages

+

Build packages

+

Luet provides an abstraction layer on top of the container image layer to make the package a first class construct. A package definition and all its dependencies are translated by Luet to Dockerfiles which can then be built anywhere that docker runs.

+

To resolve the dependency tree Luet uses a SAT solver and no database. It is responsible for calculating the dependencies of a package and to prevent conflicts. The Luet core is still young, but it has a comprehensive test suite that we use to validate any future changes.

+

Building a package with Luet requires only a definition. This definition can be self-contained and be only composed of one specfile, or a group of them, forming a Luet tree. For more complex use-cases, see collections.

+

Run luet build --help to get more help for each parameter.

+

Build accepts a list of packages to build, which syntax is in the category/name-version notation. See also specfile documentation page to see how to express packages from the CLI.

+

Environmental variables

+

Luet builds passes its environment variable at the engine which is called during build, so for example the environment variable DOCKER_HOST or DOCKER_BUILDKIT can be setted.

+

Every argument from the CLI can be setted via environment variable too with a LUET_ prefix, for instance the flag --clean, can be setted via environment with LUET_CLEAN, --privileged can be enabled with LUET_PRIVILEGED and so on.

+

Supported compression format

+

At the moment, luet can compress packages and tree with zstd and gzip. For example:

+
luet build --compression zstd ...
+

Will output package compressed in the zstd format.

+

See the --help of create-repo and build to learn all the available options.

+

Example

+

A package definition is composed of a build.yaml and a sibiling definition.yaml.

+

In the following example, we are creating a dummy package (bar/foo). Which ships one file only, /foo

+
$> # put yourself in some workdir
+
+$~/workdir> mkdir package
+
+$~/workdir> cat <<EOF > package/build.yaml
+image: busybox
+steps:
+- echo "foo=bar" > /foo
+EOF
+
+$~/workdir> cat <<EOF > package/definition.yaml
+name: "foo"
+version: "0.1"
+category: "bar"
+EOF
+
+

To build it, simply run luet build bar/foo or luet build --all to build all the packages in the current directory:

+
$> luet build --all
+
+📦  Selecting  foo 0.1
+📦  Compiling foo version 0.1 .... ☕
+🐋  Downloading image luet/cache-foo-bar-0.1-builder
+🐋  Downloading image luet/cache-foo-bar-0.1
+📦   foo Generating 🐋  definition for builder image from busybox
+🐋  Building image luet/cache-foo-bar-0.1-builder
+🐋  Building image luet/cache-foo-bar-0.1-builder done
+ Sending build context to Docker daemon  4.096kB
+ ...
+
+

Luet “trees” are just a group of specfiles, in the above example, our tree was the current directory. You can also specify a directory with the --tree option. Luet doesn’t enforce any tree layout, so they can be nested at any level. The only rule of thumb is that a build.yaml file needs to have either a definition.yaml or a collection.yaml file next to it.

+

Nesting dependencies

+

In the example above we have created a package from a delta. Luet by default creates packages by analyzing the differences between the generated containers, and extracts the differences as archive, the resulting files then are compressed and can be consumed later on by luet install.

+

Luet can create packages from different building strategies: by delta, by taking a whole container content, or by considering a single directory in the build container.

+

Besides that, a package can reference a strict dependency on others.

+

Example

+

Let’s extend the above example with two packages which depends on it during the build phase.

+

+$~/workdir> mkdir package2
+
+$~/workdir> cat <<EOF > package2/build.yaml
+requires:
+- name: "foo"
+  category: "bar"
+  version: ">=0"
+
+steps:
+- source /foo && echo "$foo" > /bar
+EOF
+
+$~/workdir> cat <<EOF > package2/definition.yaml
+name: "ineedfoo"
+version: "0.1"
+category: "bar"
+EOF
+
+
+$~/workdir> mkdir package3
+
+$~/workdir> cat <<EOF > package3/build.yaml
+requires:
+- name: "foo"
+  category: "bar"
+  version: ">=0"
+- name: "ineedfoo"
+  category: "bar"
+  version: ">=0"
+
+steps:
+- source /foo && echo "$foo" > /ineedboth
+- cat /bar > /bar
+
+EOF
+
+$~/workdir> cat <<EOF > package3/definition.yaml
+name: "ineedfooandbar"
+version: "0.1"
+category: "bar"
+EOF
+
+

To build, run again:

+
$> luet build --all
+

As we can see, now Luet generated 3 packages, bar/foo, bar/ineedfoo and bar/ineedfooandbar. They aren’t doing anything special than just shipping text files, this is an illustrative example on how build requirements can be combined to form new packages:

+

bar/ineedfooandbar depends on both bar/ineedfoo and bar/foo during build-time, while bar/foo uses a docker image as a build base.

+

See the package definition documentation page for more details on how to instruct the Luet compiler to build packages with different strategies.

+

Caching docker images

+

Luet can push and pull the docker images that are being generated during the build process. A tree is represented by a single docker image, and each package can have one or more tags attached to it.

+

To push automatically docker images that are built, use the --push option, to pull, use the --pull option. An image repository can be specified with --image-repository flag, and can include also the remote registries where the images are pushed to.

+

Luet doesn’t handle login to registries, so that has to be handled separately with docker login or img login before the build process starts.

+

Build faster

+

When packages are cached, for iterating locally it’s particularly useful to jump straight to the image that you want to build. You can use --only-target-package to jump directly to the image you are interested in. Luet will take care of checking if the images are present in the remote registry, and would build them if any of those are missing.

+

Notes

+
    +
  • All the files which are next to a build.yaml are copied in the container which is running your build, so they are always accessible during build time.
  • +
  • If you notice errors about disk space, mind to set the TMPDIR env variable to a different folder. By default luet respects the O.S. default (which in the majority of system is /tmp).
  • +
+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/concepts/overview/constraints/index.html b/docs/concepts/overview/constraints/index.html new file mode 100644 index 00000000..307b5d3c --- /dev/null +++ b/docs/concepts/overview/constraints/index.html @@ -0,0 +1,498 @@ + + + + + + + + + + + + + + + + + + + + +CSP, SAT && RL | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

CSP, SAT && RL

+
How Luet turns Image resolution into CSP
+ +

Under the hood, Luet uses boolean satisfiability problem (SAT) reinforcement learning techniques to solve package constraints.

+

Luet allows you to specify 3 types of set of contraints on a package definition:

+
    +
  • Requires
  • +
  • Conflicts
  • +
  • Provides
  • +
+

The package definition in your tree definition, along with its Requires and Conflicts, are turned into Boolean formulas that are consumed by the solver to compute a solution. The solution represent the state of your system after a particular query is asked to the solver (Install, Uninstall, Upgrade).

+

Requires and Conflicts

+

A list of requires and conflicts, composed of one or more packages, becomes a SAT formula. The formula is then given to the SAT solver to compute a finite state set of packages which must be installed in the system in order to met the requirements.

+

As Luet allows to express constraints with selectors ( e.g. A depends on >=B-1.0) it generates additional constraints to guarantee that at least one package and at most one is picked as dependency (ALO and AMO).

+

Provides

+

Provides constraints are not encoded in a SAT formula. Instead, they are expanded into an in-place substitution of the packages that they have to be replaced with. +They share the same SAT logic of expansion, allowing to swap entire version ranges (e.g. >=1.0), allowing to handle package rename, removals, and virtuals.

+

References

+ + + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/concepts/overview/index.html b/docs/concepts/overview/index.html new file mode 100644 index 00000000..29aefee5 --- /dev/null +++ b/docs/concepts/overview/index.html @@ -0,0 +1,534 @@ + + + + + + + + + + + + + + + + + + + + + +Overview | Luet + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Overview

+
See Luet in action.
+ +

Luet provides an abstraction layer on top of the container image layer to make the package a first class construct. A package definition and all its dependencies are translated by Luet to Dockerfiles which can then be built anywhere that docker runs.

+

Luet is written entirely in Go and comes as a single static binary. This has a few advantages:

+
    +
  • Easy to recover. You can use luet to bootstrap the system entirely from the ground-up.
  • +
  • Package manager has no dependencies on the packages that it installs. There is no chance of breaking the package manager by installing a conflicting package, or uninstalling one.
  • +
  • Portable - it can run on any architecture
  • +
+

Luet brings the containers ecosystem to standard software package management and delivery. It is fully built around the container concept, and leverages the huge catalog already present in the wild. It lets you use Docker images from Docker Hub, or from private registries to build packages, and helps you to redistribute them.

+

Systems that are using luet as a package manager can consume Luet repositories with only luet itself. No dependency is required by the Package manager, giving you the full control on what you install or not in the system. It can be used to generate Linux from Scratch distributions, also to build Docker images, or to simply build standalone packages that you might want to redistribute.

+

The syntax proposed aims to be KISS - you define a set of steps that need to be run to build your image, and a set of constraints denoting the requirements or conflicts of your package.

+

Why another Package manager?

+

There is no known package manager with 0-dependency that fully leverages the container ecosystem. This gap forces current package managers to depend on a specific system layout as base of the building process and the corresponding depencies. This can cause situations leading to a broken system. We want to fix that by empowering the user, by building their own packages, and redistribute them. +Luet allows also to create packages entirely from Docker images content. In this way the user can actually bundle all the files of an image into a package and deliver part of it, or entirely as a layer. All of that, without the package manager depending on a single bit from it.

+

Package definitions

+

Luet uses YAML for the package specification format, Luet parses the requirements to build packages, so Luet can consume them.

+

Below you can find links to tutorials on how to build packages, images and repositories.

+ +
+ + + + + + + + +
+ + +
+
+ Building packages +
+

How to build packages with Luet

+
+ + +
+
+ Creating Luet repositories +
+

How to create Luet repositories

+
+ + +
+
+ CLI usage +
+

How to install packages, manage repositories, …

+
+ + +
+
+ CSP, SAT && RL +
+

How Luet turns Image resolution into CSP

+
+ + +
+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/concepts/overview/index.xml b/docs/concepts/overview/index.xml new file mode 100644 index 00000000..2aa38c68 --- /dev/null +++ b/docs/concepts/overview/index.xml @@ -0,0 +1,334 @@ + + + Luet – Overview + https://luet-lab.github.io/docs/docs/concepts/overview/ + Recent content in Overview on Luet + Hugo -- gohugo.io + + + + + + + + + + + Docs: Building packages + https://luet-lab.github.io/docs/docs/concepts/overview/build_packages/ + Thu, 05 Jan 2017 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/overview/build_packages/ + + + + <h2 id="prerequisistes">Prerequisistes</h2> +<p>Luet currently supports <a href="https://www.docker.com/">Docker</a> and <a href="https://github.com/genuinetools/img">Img</a> as backends to build packages. Both of them can be used and switched in runtime with the <code>--backend</code> option, so either one of them must be present in the host system.</p> +<h3 id="docker">Docker</h3> +<p>Docker is the (less) experimental Luet engine supported. Be sure to have Docker installed and the daemon running. The user running <code>luet</code> commands needs the corresponding permissions to run the <code>docker</code> executable, and to connect to a <code>docker</code> daemon. The only feature needed by the daemon is the ability to build images, so it fully supports remote daemon as well (this can be specified with the <code>DOCKER_HOST</code> environment variable, that is respected by <code>luet</code>)</p> +<h3 id="img">Img</h3> +<p>Luet supports <a href="https://github.com/genuinetools/img">Img</a>. To use it, simply install it in your system, and while running <code>luet build</code>, you can switch the backend by providing it as a parameter: <code>luet build --backend img</code>. For small packages it is particularly powerful, as it doesn&rsquo;t require any docker daemon running in the host.</p> +<h3 id="building-packages-on-kubernetes">Building packages on Kubernetes</h3> +<p>Luet and img can be used together to orchestrate package builds also on kubernetes. There is available an experimental <a href="https://github.com/mudler/luet-k8s">Kubernetes CRD for Luet</a> which allows to build packages seamelessly in Kubernetes and push package artifacts to an S3 Compatible object storage (e.g. Minio).</p> +<h2 id="building-packages">Building packages</h2> +<p><img src="https://luet-lab.github.io/docs/docs/tree.jpg" alt="Build packages"></p> +<p>Luet provides an abstraction layer on top of the container image layer to make the package a first class construct. A package definition and all its dependencies are translated by Luet to Dockerfiles which can then be built anywhere that docker runs.</p> +<p>To resolve the dependency tree Luet uses a SAT solver and no database. It is responsible for calculating the dependencies of a package and to prevent conflicts. The Luet core is still young, but it has a comprehensive test suite that we use to validate any future changes.</p> +<p>Building a package with Luet requires only a <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile">definition</a>. This definition can be self-contained and be only composed of one <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile">specfile</a>, or a group of them, forming a Luet tree. For more complex use-cases, see <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/collections">collections</a>.</p> +<p>Run <code>luet build --help</code> to get more help for each parameter.</p> +<p>Build accepts a list of packages to build, which syntax is in the <code>category/name-version</code> notation. See also <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile/#refering-to-packages-from-the-cli">specfile documentation page</a> to see how to express packages from the CLI.</p> +<h2 id="environmental-variables">Environmental variables</h2> +<p>Luet builds passes its environment variable at the engine which is called during build, so for example the environment variable <code>DOCKER_HOST</code> or <code>DOCKER_BUILDKIT</code> can be setted.</p> +<p>Every argument from the CLI can be setted via environment variable too with a <code>LUET_</code> prefix, for instance the flag <code>--clean</code>, can be setted via environment with <code>LUET_CLEAN</code>, <code>--privileged</code> can be enabled with <code>LUET_PRIVILEGED</code> and so on.</p> +<h2 id="supported-compression-format">Supported compression format</h2> +<p>At the moment, <code>luet</code> can compress packages and tree with <code>zstd</code> and <code>gzip</code>. For example:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">luet build --compression zstd ... +</code></pre></div><p>Will output package compressed in the zstd format.</p> +<p>See the <code>--help</code> of <code>create-repo</code> and <code>build</code> to learn all the available options.</p> +<h2 id="example">Example</h2> +<p>A <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile">package definition</a> is composed of a <code>build.yaml</code> and a sibiling <code>definition.yaml</code>.</p> +<p>In the following example, we are creating a dummy package (<code>bar/foo</code>). Which ships one file only, <code>/foo</code></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$&gt; <span style="color:#8f5902;font-style:italic"># put yourself in some workdir</span> + +$~/workdir&gt; mkdir package + +$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package/build.yaml +</span><span style="color:#4e9a06">image: busybox +</span><span style="color:#4e9a06">steps: +</span><span style="color:#4e9a06">- echo &#34;foo=bar&#34; &gt; /foo +</span><span style="color:#4e9a06">EOF</span> + +$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package/definition.yaml +</span><span style="color:#4e9a06">name: &#34;foo&#34; +</span><span style="color:#4e9a06">version: &#34;0.1&#34; +</span><span style="color:#4e9a06">category: &#34;bar&#34; +</span><span style="color:#4e9a06">EOF</span> + +</code></pre></div><p>To build it, simply run <code>luet build bar/foo</code> or <code>luet build --all</code> to build all the packages in the current directory:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$&gt; luet build --all + +📦 Selecting foo 0.1 +📦 Compiling foo version 0.1 .... ☕ +🐋 Downloading image luet/cache-foo-bar-0.1-builder +🐋 Downloading image luet/cache-foo-bar-0.1 +📦 foo Generating 🐋 definition <span style="color:#204a87;font-weight:bold">for</span> builder image from busybox +🐋 Building image luet/cache-foo-bar-0.1-builder +🐋 Building image luet/cache-foo-bar-0.1-builder <span style="color:#204a87;font-weight:bold">done</span> + Sending build context to Docker daemon 4.096kB + ... + +</code></pre></div><p>Luet &ldquo;trees&rdquo; are just a group of specfiles, in the above example, our tree was the current directory. You can also specify a directory with the <code>--tree</code> option. Luet doesn&rsquo;t enforce any tree layout, so they can be nested at any level. The only rule of thumb is that a <code>build.yaml</code> file needs to have either a <code>definition.yaml</code> or a <code>collection.yaml</code> file next to it.</p> +<h2 id="nesting-dependencies">Nesting dependencies</h2> +<p>In the example above we have created a package from a <code>delta</code>. Luet by default creates packages by analyzing the differences between the generated containers, and extracts the differences as archive, the resulting files then are compressed and can be consumed later on by <code>luet install</code>.</p> +<p>Luet can create packages from different <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile/#building-strategies">building strategies</a>: by delta, by taking a whole container content, or by considering a single directory in the build container.</p> +<p>Besides that, <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile/#build-time-dependencies">a package can reference a strict dependency on others</a>.</p> +<h3 id="example-1">Example</h3> +<p>Let&rsquo;s extend the above example with two packages which depends on it during the build phase.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$~/workdir&gt; mkdir package2 + +$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package2/build.yaml +</span><span style="color:#4e9a06">requires: +</span><span style="color:#4e9a06">- name: &#34;foo&#34; +</span><span style="color:#4e9a06"> category: &#34;bar&#34; +</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34; +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06">steps: +</span><span style="color:#4e9a06">- source /foo &amp;&amp; echo &#34;$foo&#34; &gt; /bar +</span><span style="color:#4e9a06">EOF</span> + +$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package2/definition.yaml +</span><span style="color:#4e9a06">name: &#34;ineedfoo&#34; +</span><span style="color:#4e9a06">version: &#34;0.1&#34; +</span><span style="color:#4e9a06">category: &#34;bar&#34; +</span><span style="color:#4e9a06">EOF</span> + + +$~/workdir&gt; mkdir package3 + +$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package3/build.yaml +</span><span style="color:#4e9a06">requires: +</span><span style="color:#4e9a06">- name: &#34;foo&#34; +</span><span style="color:#4e9a06"> category: &#34;bar&#34; +</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34; +</span><span style="color:#4e9a06">- name: &#34;ineedfoo&#34; +</span><span style="color:#4e9a06"> category: &#34;bar&#34; +</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34; +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06">steps: +</span><span style="color:#4e9a06">- source /foo &amp;&amp; echo &#34;$foo&#34; &gt; /ineedboth +</span><span style="color:#4e9a06">- cat /bar &gt; /bar +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06">EOF</span> + +$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package3/definition.yaml +</span><span style="color:#4e9a06">name: &#34;ineedfooandbar&#34; +</span><span style="color:#4e9a06">version: &#34;0.1&#34; +</span><span style="color:#4e9a06">category: &#34;bar&#34; +</span><span style="color:#4e9a06">EOF</span> + +</code></pre></div><p>To build, run again:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$&gt; luet build --all +</code></pre></div><p>As we can see, now Luet generated 3 packages, <code>bar/foo</code>, <code>bar/ineedfoo</code> and <code>bar/ineedfooandbar</code>. They aren&rsquo;t doing anything special than just shipping text files, this is an illustrative example on how build requirements can be combined to form new packages:</p> +<p><code>bar/ineedfooandbar</code> depends on both <code>bar/ineedfoo</code> and <code>bar/foo</code> during build-time, while <code>bar/foo</code> uses a docker image as a build base.</p> +<p>See the <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile/#building-strategies">package definition documentation page</a> for more details on how to instruct the Luet compiler to build packages with different strategies.</p> +<h2 id="caching-docker-images">Caching docker images</h2> +<p>Luet can push and pull the docker images that are being generated during the build process. A tree is represented by a single docker image, and each package can have one or more tags attached to it.</p> +<p>To push automatically docker images that are built, use the <code>--push</code> option, to pull, use the <code>--pull</code> option. An image repository can be specified with <code>--image-repository</code> flag, and can include also the remote registries where the images are pushed to.</p> +<p>Luet doesn&rsquo;t handle login to registries, so that has to be handled separately with <code>docker login</code> or <code>img login</code> before the build process starts.</p> +<h3 id="build-faster">Build faster</h3> +<p>When packages are cached, for iterating locally it&rsquo;s particularly useful to jump straight to the image that you want to build. You can use <code>--only-target-package</code> to jump directly to the image you are interested in. Luet will take care of checking if the images are present in the remote registry, and would build them if any of those are missing.</p> +<h2 id="notes">Notes</h2> +<ul> +<li>All the files which are next to a <code>build.yaml</code> are copied in the container which is running your build, so they are always accessible during build time.</li> +<li>If you notice errors about disk space, mind to set the <code>TMPDIR</code> env variable to a different folder. By default luet respects the O.S. default (which in the majority of system is <code>/tmp</code>).</li> +</ul> + + + + + + Docs: Creating Luet repositories + https://luet-lab.github.io/docs/docs/concepts/overview/repositories/ + Thu, 05 Jan 2017 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/overview/repositories/ + + + + <p>After a set of packages has been built, a repository must be created in order to make them accessible by Luet clients. A Repository can be served either local files or via http(s) (at the moment of writing). Luet, by default, supports multiple-repositories with priorities.</p> +<h2 id="create-a-repository">Create a repository</h2> +<p>After issuing a <code>luet build</code>, the built packages are present in the output build directory. The <code>create-repo</code> step is needed to generate a portable tree, which is read by the clients, and a <code>repository.yaml</code> which contains the repository metadata.</p> +<p>Note that the output of <code>create-repo</code> is <em>additive</em> so it integrates with the current build content. The repository is composed by the packages generated by the <code>build</code> command (or <code>pack</code>) and the <code>create-repo</code> generated metadata.</p> +<h3 id="flags">Flags</h3> +<p>Some of the relevant flags for <code>create-repo</code> are:</p> +<ul> +<li><strong>&ndash;descr</strong>: Repository description</li> +<li><strong>&ndash;name</strong>: Repository name</li> +<li><strong>&ndash;output</strong>: Metadata output folder (while a different path can be specified, it&rsquo;s prefered to output the metadata files directly to the package directory).This most of the time matches the packages path for convenience.</li> +<li><strong>&ndash;packages</strong>: Directory where built packages are stored. This most of the time is also the output path.</li> +<li><strong>&ndash;reset-revision</strong>: Reset the repository revision number</li> +<li><strong>&ndash;tree-path</strong>: Specify a custom name for the tree path. (Defaults to tree.tar)</li> +<li><strong>&ndash;tree-compression</strong>: Specify a compression algorithm for the tree. (Available: gzip, Defaults: none)</li> +<li><strong>&ndash;tree</strong>: Path of the tree which was used to generate the packages and holds package metadatas</li> +<li><strong>&ndash;type</strong>: Repository type (http/local). It is just descriptive, the clients will be able to consume the repo in whatsoever way it is served.</li> +<li><strong>&ndash;urls</strong>: List of URIS where the repository is available</li> +</ul> +<p>See <code>luet create-repo --help</code> for a full description.</p> +<h2 id="example">Example</h2> +<p>Build a package and generate the repository metadata:</p> +<pre tabindex="0"><code>$&gt; mkdir package + +$&gt; cat &lt;&lt;EOF &gt; package/build.yaml +image: busybox +steps: +- echo &quot;foo&quot; &gt; /foo +EOF + +$&gt; cat &lt;&lt;EOF &gt; package/definition.yaml +name: &quot;foo&quot; +version: &quot;0.1&quot; +category: &quot;bar&quot; # optional! +EOF + +$&gt; luet build --all --destination $PWD/out/ --tree $PWD/package + +📦 Selecting foo 0.1 +📦 Compiling foo version 0.1 .... ☕ +🐋 Downloading image luet/cache-foo-bar-0.1-builder +🐋 Downloading image luet/cache-foo-bar-0.1 +📦 foo Generating 🐋 definition for builder image from busybox +🐋 Building image luet/cache-foo-bar-0.1-builder +🐋 Building image luet/cache-foo-bar-0.1-builder done + Sending build context to Docker daemon 4.096kB + ... + +$&gt; luet create-repo --name &quot;test&quot; --output $PWD/out --packages $PWD/out --tree $PWD/package + For repository test creating revision 1 and last update 1580641614... + +$&gt; ls out +foo-bar-0.1-builder.image.tar foo-bar-0.1.image.tar foo-bar-0.1.metadata.yaml foo-bar-0.1.package.tar repository.yaml tree.tar + +</code></pre><h3 id="repositories-type">Repositories type</h3> +<p>There are 3 types of repositories supported by luet: <code>disk</code>, <code>http</code>, <code>docker</code>.</p> +<h4 id="disk"><code>disk</code></h4> +<p>It is a repository which is merely a local folder in your system. When creating a repository and specifying <code>--output</code>, <code>luet</code> expects a local path to the system where to store the generated metadata.</p> +<h4 id="http"><code>http</code></h4> +<p>It is a repository type which is hosted behind a webserver. When creating a repository and specifying <code>--output</code>, <code>luet</code> expects a local path to the system where to store the generated metadata, similarly to the <code>disk</code> repository type. Luet is not handling any file upload. The <code>http</code> repository type gains meaning when being used from the client, where the repository source must be specified</p> +<h4 id="docker"><code>docker</code></h4> +<p>When specifying the <code>docker</code> repository type, <code>luet</code> will generate final images from the build results and upload them to the docker reference specified with <code>--output</code>. The images contains the artifact output from the build result, and they are tagged accordingly to their package name. A single image reference needs to be passed, all the packages will be pushed in a single image but with different tags.</p> +<p>The login to the container registry is not handled, the daemon needs to have already proper permissions to push the image to the destination.</p> +<h2 id="notes">Notes</h2> +<ul> +<li>The tree of definition being used to build the repository, and the package directories must <strong>not</strong> be symlinks.</li> +<li>To build a repository is not required to hold the packages artifacts, only the respective <code>metadata.yaml</code> file is required.</li> +</ul> + + + + + + Docs: CLI usage + https://luet-lab.github.io/docs/docs/concepts/overview/usage/ + Sat, 14 Dec 2019 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/overview/usage/ + + + + <h2 id="installing-a-package">Installing a package</h2> +<p>To install a package with <code>luet</code>, simply run:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet install &lt;package_name&gt; + +</code></pre></div><p>To relax dependency constraints and avoid auto-upgrades, add the <code>--relax</code> flag:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet install --relax &lt;package name&gt; +</code></pre></div><p>To install only the package without considering the deps, add the <code>--nodeps</code> flag:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet install --nodeps &lt;package name&gt; +</code></pre></div><p>To install only package dependencies, add the <code>--onlydeps</code> flag:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet install --onlydeps &lt;package name&gt; +</code></pre></div><p>To only download packages, without installing them use the <code>--download-only</code> flag:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet install --download-only &lt;package name&gt; +</code></pre></div><h2 id="uninstalling-a-package">Uninstalling a package</h2> +<p>To uninstall a package with <code>luet</code>, simply run:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet uninstall &lt;package_name&gt; + +</code></pre></div><h2 id="upgrading-the-system">Upgrading the system</h2> +<p>To upgrade your system, simply run:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet upgrade +</code></pre></div><h2 id="refreshing-repositories">Refreshing repositories</h2> +<p>Luet automatically syncs repositories definition on the machine when necessary, but it avoids to sync up in a 24h range. In order to refresh the repositories manually, run:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet repo update +</code></pre></div><h2 id="searching-a-package">Searching a package</h2> +<p>To search a package:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet search &lt;regex&gt; + +</code></pre></div><p>To search a package and display results in a table:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet search --table &lt;regex&gt; + +</code></pre></div><p>To look into the installed packages:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet search --installed &lt;regex&gt; + +</code></pre></div><p>Note: the regex argument is optional</p> +<h2 id="search-file-belonging-to-packages">Search file belonging to packages</h2> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet search --file &lt;file_pattern&gt; +</code></pre></div><h3 id="search-output">Search output</h3> +<p>Search can return results in the terminal in different ways: as terminal output, as json or as yaml.</p> +<h4 id="json">JSON</h4> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet search --json &lt;regex&gt; + +</code></pre></div><h4 id="yaml">YAML</h4> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet search --yaml &lt;regex&gt; + +</code></pre></div><h4 id="tabular">Tabular</h4> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet search --table &lt;regex&gt; + +</code></pre></div><h2 id="quiet-luet-output">Quiet luet output</h2> +<p>Luet output is verbose by default and colourful, however will try to adapt to the terminal, based on which environment is executed (as a service, in the terminal, etc.)</p> +<p>You can quiet <code>luet</code> output with the <code>--quiet</code> flag or <code>-q</code> to have a more compact output in all the commands.</p> + + + + + + Docs: CSP, SAT && RL + https://luet-lab.github.io/docs/docs/concepts/overview/constraints/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/overview/constraints/ + + + + <p>Under the hood, Luet uses boolean satisfiability problem (<a href="https://en.wikipedia.org/wiki/Boolean_satisfiability_problem">SAT</a>) <a href="https://en.wikipedia.org/wiki/Reinforcement_learning">reinforcement learning</a> techniques to solve package constraints.</p> +<p>Luet allows you to specify 3 types of set of contraints on a <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/">package</a> definition:</p> +<ul> +<li>Requires</li> +<li>Conflicts</li> +<li>Provides</li> +</ul> +<p>The package definition in your tree definition, along with its Requires and Conflicts, are turned into Boolean formulas that are consumed by the solver to compute a solution. The solution represent the state of your system after a particular query is asked to the solver (Install, Uninstall, Upgrade).</p> +<h2 id="requires-and-conflicts">Requires and Conflicts</h2> +<p>A list of requires and conflicts, composed of one or more <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/">packages</a>, becomes a SAT formula. The formula is then given to the SAT solver to compute a finite state set of packages which must be installed in the system in order to met the requirements.</p> +<p>As Luet allows to express constraints with selectors ( e.g. <code>A depends on &gt;=B-1.0</code>) it generates additional constraints to guarantee that at least one package and at most one is picked as dependency (<em>ALO</em> and <em>AMO</em>).</p> +<h2 id="provides">Provides</h2> +<p>Provides constraints are not encoded in a SAT formula. Instead, they are <code>expanded</code> into an in-place substitution of the packages that they have to be replaced with. +They share the same SAT logic of expansion, allowing to swap entire version ranges (e.g. <code>&gt;=1.0</code>), allowing to handle package rename, removals, and virtuals.</p> +<h2 id="references">References</h2> +<ul> +<li>OPIUM (Luet is inspired by it): <a href="https://ranjitjhala.github.io/static/opium.pdf">https://ranjitjhala.github.io/static/opium.pdf</a></li> +<li>FROM TRACTABLE CSP TO TRACTABLE SAT: <a href="https://www.cs.ox.ac.uk/files/4014/maxclosed_orderencoding_v16_TR.pdf">https://www.cs.ox.ac.uk/files/4014/maxclosed_orderencoding_v16_TR.pdf</a></li> +<li>Solver concepts applied to packages (<code>zypper</code>): <a href="https://en.opensuse.org/openSUSE:Libzypp_satsolver_basics">https://en.opensuse.org/openSUSE:Libzypp_satsolver_basics</a></li> +</ul> + + + + + + diff --git a/docs/concepts/overview/repositories/index.html b/docs/concepts/overview/repositories/index.html new file mode 100644 index 00000000..493670ff --- /dev/null +++ b/docs/concepts/overview/repositories/index.html @@ -0,0 +1,553 @@ + + + + + + + + + + + + + + + + + + + + +Creating Luet repositories | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Creating Luet repositories

+
How to create Luet repositories
+ +

After a set of packages has been built, a repository must be created in order to make them accessible by Luet clients. A Repository can be served either local files or via http(s) (at the moment of writing). Luet, by default, supports multiple-repositories with priorities.

+

Create a repository

+

After issuing a luet build, the built packages are present in the output build directory. The create-repo step is needed to generate a portable tree, which is read by the clients, and a repository.yaml which contains the repository metadata.

+

Note that the output of create-repo is additive so it integrates with the current build content. The repository is composed by the packages generated by the build command (or pack) and the create-repo generated metadata.

+

Flags

+

Some of the relevant flags for create-repo are:

+
    +
  • –descr: Repository description
  • +
  • –name: Repository name
  • +
  • –output: Metadata output folder (while a different path can be specified, it’s prefered to output the metadata files directly to the package directory).This most of the time matches the packages path for convenience.
  • +
  • –packages: Directory where built packages are stored. This most of the time is also the output path.
  • +
  • –reset-revision: Reset the repository revision number
  • +
  • –tree-path: Specify a custom name for the tree path. (Defaults to tree.tar)
  • +
  • –tree-compression: Specify a compression algorithm for the tree. (Available: gzip, Defaults: none)
  • +
  • –tree: Path of the tree which was used to generate the packages and holds package metadatas
  • +
  • –type: Repository type (http/local). It is just descriptive, the clients will be able to consume the repo in whatsoever way it is served.
  • +
  • –urls: List of URIS where the repository is available
  • +
+

See luet create-repo --help for a full description.

+

Example

+

Build a package and generate the repository metadata:

+
$> mkdir package
+
+$> cat <<EOF > package/build.yaml
+image: busybox
+steps:
+- echo "foo" > /foo
+EOF
+
+$> cat <<EOF > package/definition.yaml
+name: "foo"
+version: "0.1"
+category: "bar" # optional!
+EOF
+
+$> luet build --all --destination $PWD/out/ --tree $PWD/package
+
+📦  Selecting  foo 0.1
+📦  Compiling foo version 0.1 .... ☕
+🐋  Downloading image luet/cache-foo-bar-0.1-builder
+🐋  Downloading image luet/cache-foo-bar-0.1
+📦   foo Generating 🐋  definition for builder image from busybox
+🐋  Building image luet/cache-foo-bar-0.1-builder
+🐋  Building image luet/cache-foo-bar-0.1-builder done
+ Sending build context to Docker daemon  4.096kB
+ ...
+
+$> luet create-repo --name "test" --output $PWD/out --packages $PWD/out --tree $PWD/package
+ For repository test creating revision 1 and last update 1580641614...
+
+$> ls out
+foo-bar-0.1-builder.image.tar  foo-bar-0.1.image.tar  foo-bar-0.1.metadata.yaml  foo-bar-0.1.package.tar  repository.yaml  tree.tar
+
+

Repositories type

+

There are 3 types of repositories supported by luet: disk, http, docker.

+

disk

+

It is a repository which is merely a local folder in your system. When creating a repository and specifying --output, luet expects a local path to the system where to store the generated metadata.

+

http

+

It is a repository type which is hosted behind a webserver. When creating a repository and specifying --output, luet expects a local path to the system where to store the generated metadata, similarly to the disk repository type. Luet is not handling any file upload. The http repository type gains meaning when being used from the client, where the repository source must be specified

+

docker

+

When specifying the docker repository type, luet will generate final images from the build results and upload them to the docker reference specified with --output. The images contains the artifact output from the build result, and they are tagged accordingly to their package name. A single image reference needs to be passed, all the packages will be pushed in a single image but with different tags.

+

The login to the container registry is not handled, the daemon needs to have already proper permissions to push the image to the destination.

+

Notes

+
    +
  • The tree of definition being used to build the repository, and the package directories must not be symlinks.
  • +
  • To build a repository is not required to hold the packages artifacts, only the respective metadata.yaml file is required.
  • +
+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/concepts/overview/usage/index.html b/docs/concepts/overview/usage/index.html new file mode 100644 index 00000000..be09fb13 --- /dev/null +++ b/docs/concepts/overview/usage/index.html @@ -0,0 +1,543 @@ + + + + + + + + + + + + + + + + + + + + +CLI usage | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

CLI usage

+
How to install packages, manage repositories, …
+ +

Installing a package

+

To install a package with luet, simply run:

+

+$ luet install <package_name>
+
+

To relax dependency constraints and avoid auto-upgrades, add the --relax flag:

+
$ luet install --relax <package name>
+

To install only the package without considering the deps, add the --nodeps flag:

+
$ luet install --nodeps <package name>
+

To install only package dependencies, add the --onlydeps flag:

+
$ luet install --onlydeps <package name>
+

To only download packages, without installing them use the --download-only flag:

+
$ luet install --download-only <package name>
+

Uninstalling a package

+

To uninstall a package with luet, simply run:

+

+$ luet uninstall <package_name>
+
+

Upgrading the system

+

To upgrade your system, simply run:

+
$ luet upgrade
+

Refreshing repositories

+

Luet automatically syncs repositories definition on the machine when necessary, but it avoids to sync up in a 24h range. In order to refresh the repositories manually, run:

+
$ luet repo update
+

Searching a package

+

To search a package:

+

+$ luet search <regex>
+
+

To search a package and display results in a table:

+

+$ luet search --table <regex>
+
+

To look into the installed packages:

+

+$ luet search --installed <regex>
+
+

Note: the regex argument is optional

+

Search file belonging to packages

+
$ luet search --file <file_pattern>
+

Search output

+

Search can return results in the terminal in different ways: as terminal output, as json or as yaml.

+

JSON

+

+$ luet search --json <regex>
+
+

YAML

+

+$ luet search --yaml <regex>
+
+

Tabular

+

+$ luet search --table <regex>
+
+

Quiet luet output

+

Luet output is verbose by default and colourful, however will try to adapt to the terminal, based on which environment is executed (as a service, in the terminal, etc.)

+

You can quiet luet output with the --quiet flag or -q to have a more compact output in all the commands.

+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/concepts/packages/collections/index.html b/docs/concepts/packages/collections/index.html new file mode 100644 index 00000000..9d5b6e17 --- /dev/null +++ b/docs/concepts/packages/collections/index.html @@ -0,0 +1,503 @@ + + + + + + + + + + + + + + + + + + + + +Collections | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Collections

+
Group a set of package build spec with templating
+ +

Collections are a special superset of packages. To define a collection, instead of using a definition.yaml file, create a collection.yaml file with a list of packages:

+ + + + + +
packages:
+- category: "test"
+  name: "foo"
+  version: "1.0"
+- category: "test"
+  name: "bar"
+  version: "1.0"
+
+ + Complete source code: https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/collection.yaml +
+ +

Packages under a collection shares the same build.yaml and finalize.yaml, so a typical package layout can be:

+
collection/
+    collection.yaml
+    build.yaml
+    finalize.yaml
+    ... additional files in the build context
+

Luet during the build phase, will treat packages of a collection individually. A collection is a way to share the same build process across different packages.

+

Templating

+

The templating mechanism can be used in collections as well, and each stanza in packages is used to interpolate each single package.

+

Examples

+ + + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/concepts/packages/index.html b/docs/concepts/packages/index.html new file mode 100644 index 00000000..7909cd7d --- /dev/null +++ b/docs/concepts/packages/index.html @@ -0,0 +1,682 @@ + + + + + + + + + + + + + + + + + + + + + +Packages | Luet + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Packages

+
Package definition syntax
+ +

A Package in Luet is denoted by a triple (name, category and version), here called package form in a definition.yaml file in YAML:

+
name: "awesome"
+version: "0.1"
+category: "foo"
+

While category and version can be omitted, the name is required. Note that when refering to a package, the triplet is always present:

+
requires:
+- name: "awesome"
+  version: "0.1"
+  category: "foo"
+- name: "bar"
+  version: "0.1"
+  category: "foo"
+

Building process

+

When a package is required to be built, Luet resolves the dependency trees and orders the spec files to satisfy the given contraints.

+

Each package build context is where the spec files are found (definition.yaml and build.yaml). This means that in the container, which is running the build process, the resources inside the package folder are accessible, as normally in Docker.

+
❯ tree distro/raspbian/buster
+distro/raspbian/buster
+├── build.sh
+├── build.yaml
+├── definition.yaml
+└── finalize.yaml
+

In the example above, build.sh is accessible in build time and can be invoked easily in build time in build.yaml:

+
steps:
+- sh build.sh
+

Package provides

+

Packages can specify a list of provides. This is a list of packages in package form, which indicates that the current definition replaces every occurrence of the packages in the list (both at build and runtime). This mechanism is particularly helpful for handling package moves or for enabling virtual packages (e.g., gentoo virtual packages).

+

Note: packages in the provides list don’t need to exist or have a valid build definition either.

+

Package types

+

By a combination of keywords in build.yaml, you end up with categories of packages that can be built:

+
    +
  • Seed packages
  • +
  • Packages deltas
  • +
  • Package layers
  • +
  • Package with includes
  • +
+

Check the Specfile concept page for a full overview of the available keywords in the Luet specfile format.

+

Seed packages

+

Seed packages denote a parent package (or root) that can be used by other packages as a dependency. Normally, seed packages include just an image (preferably tagged) used as a base for other packages to depend on.

+

It is useful to pin to specific image versions, and to write down in a tree where packages are coming from. There can be as many seed packages as you like in a tree.

+

A seed package build.yaml example is the following:

+
image: "alpine:3.1"
+

Every other package that depends on it will inherit the layers from it.

+

If you want to extract the content of the seed package in a separate packages (splitting), you can just create as many package as you wish depending on that one, and extract its content, for example:

+

alpine/build.yaml

+
image: "alpine:3.1"
+

alpine/definition.yaml

+
name: "alpine"
+version: "3.1"
+category: "seed"
+

sh/build.yaml

+
# List of build-time dependencies
+requires:
+- name: "alpine"
+  version: "3.1"
+  category: "seed"
+unpack: true # Tells luet to use the image content by unpacking it
+includes: 
+- /bin/sh
+

sh/definition.yaml

+
name: "sh"
+category: "utils"
+version: "1.0"
+

In this example, there are two packages being specified:

+
    +
  • One is the seed package, which is the base image employed to later extract packages. It has no installable content, and it is just virtually used during build phase.
  • +
  • sh is the package which contains /bin/sh, extracted from the seed image and packaged. This can be consumed by Luet clients in order to install sh in their system.
  • +
+

Packages delta

+

Luet, by default, will try to calculate the delta of the package that is meant to be built. This means that it tracks incrementally the changes in the packages, to ease the build definition. Let’s see an example.

+

Given the root package: +alpine/build.yaml

+
image: "alpine:3.1"
+

alpine/definition.yaml

+
name: "alpine"
+version: "3.1"
+category: "seed"
+

We can generate any file, and include it in our package by defining this simple package:

+

foo/build.yaml

+
# List of build-time dependencies
+requires:
+- name: "alpine"
+  version: "3.1"
+  category: "seed"
+steps:
+- echo "Awesome" > /foo
+

foo/definition.yaml

+
name: "foo"
+category: "utils"
+version: "1.0"
+

By analyzing the difference between the two packages, Luet will automatically track and package /foo as part of the foo package.

+

To allow operations that must not be accounted in to the final package, you can use the prelude keyword:

+

foo/build.yaml

+
# List of build-time dependencies
+requires:
+- name: "alpine"
+  version: "3.1"
+  category: "seed"
+prelude:
+- echo "Not packaged" > /invisible
+steps:
+- echo "Awesome" > /foo
+

foo/definition.yaml

+
name: "foo"
+category: "utils"
+version: "1.0"
+

The list of commands inside prelude that would produce artifacts, are not accounted to the final package. In this example, only /foo would be packaged (which output is equivalent to the example above).

+

This can be used, for instance, to fetch sources that must not be part of the package.

+

You can apply restrictions anytime and use the includes keyword to specifically pin to the files you wish in your package.

+

Package layers

+

Luet can be used to track entire layers and make them installable by Luet clients.

+

Given the examples above:

+

alpine/build.yaml

+
image: "alpine:3.1"
+

alpine/definition.yaml

+
name: "alpine"
+version: "3.1"
+category: "seed"
+

An installable package derived by the seed, with the actual full content of the layer can be composed as follows:

+

foo/build.yaml

+
# List of build-time dependencies
+requires:
+- name: "alpine"
+  version: "3.1"
+  category: "seed"
+unpack: true # It advertize Luet to consume the package as is
+

foo/definition.yaml

+
name: "foo"
+category: "utils"
+version: "1.0"
+

This can be combined with other keywords to manipulate the resulting package (layer), for example:

+

foo/build.yaml

+
# List of build-time dependencies
+requires:
+- name: "alpine"
+  version: "3.1"
+  category: "seed"
+unpack: true # It advertize Luet to consume the package as is
+steps:
+- apk update
+- apk add git
+- apk add ..
+

foo/definition.yaml

+
name: "foo"
+category: "utils"
+version: "1.0"
+

Package includes

+

In addition, the includes keyword can be set in order to extract portions from the package image.

+

git/build.yaml

+
# List of build-time dependencies
+requires:
+- name: "alpine"
+  version: "3.1"
+  category: "seed"
+unpack: true # It advertize Luet to consume the package as is
+steps:
+- apk update
+- apk add git
+includes:
+- /usr/bin/git
+

foo/definition.yaml

+
name: "git"
+category: "utils"
+version: "1.0"
+

As a reminder, the includes keywords accepts regular expressions in the Golang format. Any criteria expressed by means of Golang regular expressions, and matching the file name (absolute path), will be part of the final package.

+ +
+ + + + + + + + +
+ + +
+
+ Specfile +
+

Luet specfile syntax

+
+ + +
+
+ Templated packages +
+

Use templates to fine tune build specs

+
+ + +
+
+ Collections +
+

Group a set of package build spec with templating

+
+ + +
+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/concepts/packages/index.xml b/docs/concepts/packages/index.xml new file mode 100644 index 00000000..88def627 --- /dev/null +++ b/docs/concepts/packages/index.xml @@ -0,0 +1,587 @@ + + + Luet – Packages + https://luet-lab.github.io/docs/docs/concepts/packages/ + Recent content in Packages on Luet + Hugo -- gohugo.io + + + + + + + + + + + Docs: Specfile + https://luet-lab.github.io/docs/docs/concepts/packages/specfile/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/packages/specfile/ + + + + <h1 id="specfiles">Specfiles</h1> +<p>Luet <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/">packages</a> are defined by specfiles. Specfiles define the runtime and builtime requirements of a package. There is an hard distinction between runtime and buildtime. A spec is composed at least by the runtime (<code>definition.yaml</code> or a <code>collection.yaml</code>) and the buildtime specification (<code>build.yaml</code>).</p> +<p>Luet identifies the package definition by looking at directories that contains a <code>build.yaml</code> and a <code>definition.yaml</code> (or <code>collection.yaml</code>) files. A Luet tree is merely a composition of directories that follows this convention. There is no constriction on either folder naming or hierarchy.</p> +<p><em>Example of a <a href="https://github.com/Luet-lab/luet-embedded/tree/master/distro">tree folder hierarchy</a></em></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">tree distro +distro +├── funtoo +│   ├── 1.4 +│   │   ├── build.sh +│   │   ├── build.yaml +│   │   ├── definition.yaml +│   │   └── finalize.yaml +│   ├── docker +│   │   ├── build.yaml +│   │   ├── definition.yaml +│   │   └── finalize.yaml +│   └── meta +│   └── rpi +│   └── 0.1 +│   ├── build.yaml +│   └── definition.yaml +├── packages +│   ├── container-diff +│   │   └── 0.15.0 +│   │   ├── build.yaml +│   │   └── definition.yaml +│   └── luet +│   ├── build.yaml +│   └── definition.yaml +├── raspbian +│   ├── buster +│   │   ├── build.sh +│   │   ├── build.yaml +│   │   ├── definition.yaml +│   │   └── finalize.yaml +│   ├── buster-boot +│   │   ├── build.sh +│   │   ├── build.yaml +│   │   ├── definition.yaml +│   │   └── finalize.yaml +</code></pre></div><h2 id="build-specs">Build specs</h2> +<p>Build specs are defined in <code>build.yaml</code> files. They denote the build-time <code>dependencies</code> and <code>conflicts</code>, together with a definition of the content of the package.</p> +<p><em>Example of a <code>build.yaml</code> file</em>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo &#34;Luet is awesome&#34; &gt; /awesome</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">prelude</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo &#34;nooops!&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;echo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">provides</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">env</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">FOO=bar</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">includes</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/awesome</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">unpack</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="building-strategies">Building strategies</h3> +<p>Luet can create packages with different strategies:</p> +<ul> +<li>by delta. Luet will analyze the containers differencies to find out which files got <strong>added</strong>. +You can use the <code>prelude</code> section to exclude certains file during analysis.</li> +<li>by taking a whole container content</li> +<li>by considering a single directory in the build container.</li> +</ul> +<h4 id="package-by-delta">Package by delta</h4> +<p>By default Luet will analyze the container content and extract any file that gets <strong>added</strong> to it. The difference is calculated by using the container which is depending on, or either by the container which is created by running the steps in the <code>prelude</code> section of the package build spec:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">prelude</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#8f5902;font-style:italic"># do something...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#8f5902;font-style:italic"># real work that should be calculated delta over</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>By omitting the <code>prelude</code> keyword, the delta will be calculated from the parent container where the build will start from.</p> +<h4 id="package-by-container-content">Package by container content</h4> +<p>Luet can also generate a package content from a container. This is really useful when creating packages that are entire versioned <code>rootfs</code>. To enable this behavior, simply add <code>unpack: true</code> to the <code>build.yaml</code>. This enables the Luet unpacking features, which will extract all the files contained in the container which is built from the <code>prelude</code> and <code>steps</code> fields.</p> +<p>To include/exclude single files from it, use the <code>includes</code> and <code>excludes</code> directives.</p> +<h4 id="package-by-a-folder-in-the-final-container">Package by a folder in the final container</h4> +<p>Similarly, you can tell Luet to create a package from a folder in the build container. To enable this behavior, simply add <code>package_dir: &quot;/path/to/final/dir&quot;</code>. +The directory must represent exactly how the files will be ultimately installed from clients, and they will show up in the same layout in the final archive.</p> +<p>So for example, to create a package which ships <code>/usr/bin/mybin</code>, we could write:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">package_dir</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/output&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">mkdir -p /output/usr/bin/</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo &#34;fancy stuff&#34; &gt; /output/usr/bin/mybin &amp;&amp; chmod +x /output/usr/bin/mybin</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="build-time-dependencies">Build time dependencies</h3> +<p>A package build spec defines how a package is built. In order to do this, Luet needs to know where to start. Hence a package must declare at least either one of the following:</p> +<ul> +<li>an <code>image</code> keyword which tells which Docker image to use as base, or</li> +<li>a list of <code>requires</code>, which are references to other packages available in the tree.</li> +</ul> +<p>They can&rsquo;t be both present in the same specfile.</p> +<p>To note, it&rsquo;s not possible to mix package build definitions from different <code>image</code> sources. They must form a unique sub-graph in the build dependency tree.</p> +<p>On the other hand it&rsquo;s possible to have multiple packages depending on a combination of different <code>requires</code>, given they are coming from the same <code>image</code> parent.</p> +<h3 id="excludingincluding-files-explictly">Excluding/including files explictly</h3> +<p>Luet can also <em>exclude</em> and <em>include</em> single files or folders from a package by using the <code>excludes</code> and <code>includes</code> keyword respecitvely.</p> +<p>Both of them are parsed as a list of Golang regex expressions, and they can be combined together to fine-grainly decide which files should be inside the final artifact. You can refer to the files as they were in the resulting package. So if a package produces a <code>/foo</code> file, and you want to exclude it, you can add it to <code>excludes</code> as <code>/foo</code>.</p> +<h3 id="package-source-image">Package source image</h3> +<p>Luet needs an image to kick-off the build process for each package. This image is being used to run the commands in the <code>steps</code> and <code>prelude</code>, and then the image is processed by the <strong>building strategies</strong> explained above.</p> +<p>The image can be resolved either by:</p> +<ol> +<li>providing a specific image name with <code>image</code></li> +<li>providing a set of package requirements with <code>requires</code> which will be constructed a new image from. The resulting image is an image linked between each other with the <code>FROM</code> field in the Dockerfile following the SAT solver ordering.</li> +<li>providing a set of packages to squash their result from <code>requires</code> and by specifying <code>requires_final_images: true</code>.</li> +</ol> + + +<div class="alert alert-info" role="alert"> +<h4 class="alert-heading">Note</h4> + + The above keywords cannot be present in the same spec <strong>at the same time</strong>, or they cannot be combined. But you are free to create further intermediate specs to achieve the desired image. + +</div> + +<h4 id="difference-between-requires-and-requires-with-requires_final_images-true">Difference between <code>requires</code> and <code>requires</code> with <code>requires_final_images: true</code></h4> +<p><code>requires</code> generates a graph from all the <code>images</code> of the specfile referenced inside the list. This means it builds a chain of images that are used to build the packages, e.g.: <code>packageA(image: busybox) -&gt; packageB (requires: A) -&gt; packageC (requires: C)</code>. The container which is running your build then <strong>inherits</strong> it&rsquo;s parents from a chain of order resolution, provided by the SAT solver.</p> +<p>When specifying <code>requires_final_images: true</code> luet builds an artifact for each of the packages listed from their compilation specs and it will later <em>squash</em> them together in a new container image which is then used in the build process to create an artifact.</p> +<p>The key difference is about <em>where</em> your build is going to run from. By specifying <code>requires_final_images</code> it will be constructed a new image with the content of each package - while if setting it to false, it will order the images appropriately and link them together with the Dockerfile <code>FROM</code> field. That allows to reuse the same images used to build the packages in the require section - or - create a new one from the result of each package compilation.</p> +<h2 id="keywords">Keywords</h2> +<p>Here is a list of the full keyword refereces for the <code>build.yaml</code> file.</p> +<h3 id="conflicts"><code>conflicts</code></h3> +<p>(optional) List of packages which it conflicts with in <em>build time</em>. In the same form of <code>requires</code> it is a list of packages that the current one is conflicting with.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>See <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages">Package concepts</a> for more information on how to represent a package in a Luet tree.</p> +<h3 id="copy"><code>copy</code></h3> +<p><em>since luet&gt;=0.15.0</em></p> +<p>(optional) A list of packages/images where to copy files from. It is the <a href="https://docs.docker.com/develop/develop-images/multistage-build/">Docker multi-stage build</a> equivalent but enhanced with tree hashing resolution.</p> +<p>To copy a specific file from a package <em>build</em> container:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">prelude</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">copy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">package</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">source</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">destination</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>Any package that is listed in the section will be compiled beforeahead the package, and the file is available both in <code>prelude</code> and <code>steps</code>.</p> +<p>Internally, it&rsquo;s rendered as <code>COPY --from=package/image:sha /foo /bar</code></p> +<p>To copy a specific file from an external image:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">prelude</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">copy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;buxybox:latest&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">source</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">destination</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="env"><code>env</code></h3> +<p>(optional) A list of environment variables ( in <code>NAME=value</code> format ) that are expanded in <code>step</code> and in <code>prelude</code>. ( e.g. <code>${NAME}</code> ).</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">env</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">PATH=$PATH:/usr/local/go/bin</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">GOPATH=/luetbuild/go</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">GO111MODULE=on</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">CGO_ENABLED=0</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">LDFLAGS=&#34;-s -w&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="excludes"><code>excludes</code></h3> +<p>(optional) List of golang regexes. They are in full path form (e.g. <code>^/usr/bin/foo</code> ) and indicates that the files listed shouldn&rsquo;t be part of the final artifact</p> +<p>Wildcards and golang regular expressions are supported. If specified, files which are not matching any of the regular expressions in the list will be excluded in the final package.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">excludes</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">^/etc/shadow</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">^/etc/os-release</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">^/etc/gshadow</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>By combining <code>excludes</code> with <code>includes</code>, it&rsquo;s possible to include certain files while excluding explicitly some others (<code>excludes</code> takes precedence over <code>includes</code>).</p> +<h3 id="image"><code>image</code></h3> +<p>(optional/required) Docker image to be used to build the package.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;busybox&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>It might be omitted in place of <code>requires</code>, and indicates the image used to build the package. The image will be pulled and used to build the package.</p> +<h3 id="includes"><code>includes</code></h3> +<p>(optional) List of regular expressions to match files in the resulting package. The path is absolute as it would refer directly to the artifact content.</p> +<p>Wildcards and golang regular expressions are supported. If specified, files which are not matching any of the regular expressions in the list will be excluded in the final package.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">includes</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/etc$</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/etc/lvm$</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/etc/lvm/.*</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/usr$</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/usr/bin$</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/usr/bin/cc.*</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/usr/bin/c\+\+.*</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/usr/bin/cpp.*</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/usr/bin/g\+\+.*</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><strong>Note</strong>: Directories are treated as standard entries, so to include a single file, you need also to explictly include also it&rsquo;s directory. Consider this example to include <code>/etc/lvm/lvm.conf</code>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">includes</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/etc$</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/etc/lvm$</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/etc/lvm/lvm.conf</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="join"><code>join</code></h3> +<p><em>since luet&gt;=0.16.0</em> +<em>to be deprecated in luet&gt;=0.18.0 in favor of <code>requires_final_images</code></em></p> +<p>(optional/required) List of packages which are used to generate a parent image from.</p> +<p>It might be omitted in place of <code>image</code> or <code>requires</code>, and will generate an image which will be used as source of the package from the final packages in the above list. The new image is used to run eventually the package building process and a new artifact can be generated out of it.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">join</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>See <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages">Package concepts</a> for more information on how to represent a package in a Luet tree.</p> +<h4 id="examples">Examples</h4> +<ul> +<li><a href="https://github.com/mocaccinoOS/mocaccino-stage3/blob/278e3637cf65761bf01a22c891135e237e4717ad/packages/system/stage3/build.yaml">https://github.com/mocaccinoOS/mocaccino-stage3/blob/278e3637cf65761bf01a22c891135e237e4717ad/packages/system/stage3/build.yaml</a></li> +</ul> +<h3 id="package_dir"><code>package_dir</code></h3> +<p>(optional) A path relative to the build container where to create the package from.</p> +<p>Similarly to <code>unpack</code>, changes the building strategy.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">mkdir -p /foo/bar/etc/myapp</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">touch /foo/bar/etc/myapp/config</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">package_dir</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">/foo/bar</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="prelude"><code>prelude</code></h3> +<p>(optional) A list of commands to perform in the build container before building.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">prelude</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000;font-weight:bold">|</span><span style="color:#8f5902;font-style:italic"> +</span><span style="color:#8f5902;font-style:italic"> PACKAGE_VERSION=${PACKAGE_VERSION%\+*} &amp;&amp; \ +</span><span style="color:#8f5902;font-style:italic"> git clone https://github.com/mudler/yip &amp;&amp; cd yip &amp;&amp; git checkout &#34;${PACKAGE_VERSION}&#34; -b build</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="requires"><code>requires</code></h3> +<p>(optional/required) List of packages which it depends on.</p> +<p>A list of packages that the current package depends on in <em>build time</em>. It might be omitted in place of <code>image</code>, and determines the resolution tree of the package itself. A new image is composed from the packages listed in this section in order to build the package</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>See <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages">Package concepts</a> for more information on how to represent a package in a Luet tree.</p> +<h3 id="requires_final_images"><code>requires_final_images</code></h3> +<p><em>since luet&gt;=0.17.0</em></p> +<p>(optional) A boolean flag which instruct luet to use the final images in the <code>requires</code> field.</p> +<p>By setting <code>requires_final_images: true</code> in the compilation spec, packages in the <code>requires</code> section will be first compiled, and afterwards the final packages are squashed together in a new image that will be used during build.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">requires_final_images</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><code>requires_final_images</code> replaces the use of <code>join</code>, which will be deprecated in luet <code>&gt;=0.18.0</code>.</p> +<h3 id="step"><code>step</code></h3> +<p>(optional) List of commands to perform in the build container.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000;font-weight:bold">|</span><span style="color:#8f5902;font-style:italic"> +</span><span style="color:#8f5902;font-style:italic"> </span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">cd yip &amp;&amp; make build-small &amp;&amp; mv yip /usr/bin/yip</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="unpack"><code>unpack</code></h3> +<p>(optional) Boolean flag. It indicates to use the unpacking strategy while building a package</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">unpack</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>It indicates that the package content <strong>is</strong> the whole container content.</p> +<h2 id="rutime-specs">Rutime specs</h2> +<p>Runtime specification are denoted in a <code>definition.yaml</code> or a <code>collection.yaml</code> sibiling file. It identifies the package and the runtime contraints attached to it.</p> +<p><em>definition.yaml</em>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;awesome&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;echo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">provides</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&lt;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>A <code>collection.yaml</code> can be used in place of a <code>definition.yaml</code> to identify a <strong>set</strong> of packages that instead shares a common <code>build.yaml</code>:</p> +<p><em>collection.yaml</em>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">packages</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;awesome&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;echo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">provides</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&lt;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;awesome&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.2&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;echo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">provides</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&lt;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>All the fields (also the ones which are not part of the spec) in the <code>definition.yaml</code> file are available as templating values when rendering the <code>build.yaml</code> file. When running <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile/#finalizers">finalizers</a> instead only the fields belonging to the specs are available.</p> +<h3 id="keywords-1">Keywords</h3> +<p>Here is a list of the full keyword refereces</p> +<h3 id="annotations"><code>annotations</code></h3> +<p>(optional) A map of freeform package annotations:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">annotations</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">foo</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">baz</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h4 id="category"><code>category</code></h4> +<p>(optional) A string containing the category of the package</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;system&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="conflicts-1"><code>conflicts</code></h3> +<p>(optional) List of packages which it conflicts with in <em>runtime</em>. In the same form of <code>requires</code> it is a list of packages that the current one is conflicting with.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>See <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages">Package concepts</a> for more information on how to represent a package in a Luet tree.</p> +<h3 id="description"><code>description</code></h3> +<p>(optional) A string indicating the package description</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">description</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo is capable of...&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="hidden"><code>hidden</code></h3> +<p>(optional) A boolean indicating whether the package has to be shown or not in the search results (<code>luet search...</code>)</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">hidden</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="labels"><code>labels</code></h3> +<p>(optional) A map of freeform package labels:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">labels</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">foo</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">baz</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>Labels can be used in <code>luet search</code> to find packages by labels, e.g.:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$&gt; luet search --by-label foo +</code></pre></div><h3 id="license"><code>license</code></h3> +<p>(optional) A string indicating the package license type.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">license</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;GPL-3&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h4 id="name"><code>name</code></h4> +<p>(required) A string containing the name of the package</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="provides"><code>provides</code></h3> +<p>(optional) List of packages which the current package is providing.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>See <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages">Package concepts</a> for more information on how to represent a package in a Luet tree.</p> +<h3 id="requires-1"><code>requires</code></h3> +<p>(optional) List of packages which it depends on in runtime.</p> +<p>A list of packages that the current package depends on in <em>runtime</em>. The determines the resolution tree of the package itself.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>See <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages">Package concepts</a> for more information on how to represent a package in a Luet tree.</p> +<h3 id="uri"><code>uri</code></h3> +<p>(optional) A list of URI relative to the package ( e.g. the official project pages, wikis, README, etc )</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">uri</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#4e9a06">&#34;http://www.mocaccino.org&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h4 id="version"><code>version</code></h4> +<p>(required) A string containing the version of the package</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h2 id="refering-to-packages-from-the-cli">Refering to packages from the CLI</h2> +<p>All the <code>luet</code> commands which takes a package as argument, respect the following syntax notation:</p> +<ul> +<li><code>cat/name</code>: will default to selecting any available package</li> +<li><code>=cat/name</code>: will default to gentoo parsing with regexp so also <code>=cat/name-1.1</code> works</li> +<li><code>cat/name@version</code>: will select the specific version wanted ( e.g. <code>cat/name@1.1</code> ) but can also include ranges as well <code>cat/name@&gt;=1.1</code></li> +<li><code>name</code>: just name, category is omitted and considered empty</li> +</ul> +<h2 id="finalizers">Finalizers</h2> +<p>Finalizers are denoted in a <code>finalize.yaml</code> file, which is a sibiling of <code>definition.yaml</code> and <code>build.yaml</code> file. It contains a list of commands that finalize the package when it is installed in the machine.</p> +<p><em>finalize.yaml</em>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">install</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">rc-update add docker default</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="keywords-2">Keywords</h3> +<ul> +<li><code>install</code>: List of commands to run in the host machine. Failures are eventually ignored, but will be reported and luet will exit non-zero in such case.</li> +</ul> + + + + + + Docs: Templated packages + https://luet-lab.github.io/docs/docs/concepts/packages/templates/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/packages/templates/ + + + + <p>Luet supports the <a href="http://masterminds.github.io/sprig/"><code>sprig</code> rendering engine template, like helm</a>. It&rsquo;s being used to interpolate <code>build.yaml</code> and <code>finalize.yaml</code> files before their execution. The following document assumes you are familiar with the <code>helm</code> templating.</p> +<p>The <code>build.yaml</code> and <code>finalize.yaml</code> files are rendered during build time, and it&rsquo;s possible to use the <code>helm</code> templating syntax inside such files. The <code>definition.yaml</code> file will be used to interpolate templating values available in <code>build.yaml</code></p> +<p>Given the following <code>definition.yaml</code>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">additional_field</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>A <code>build.yaml</code> can look like the following, and interpolates it&rsquo;s values during build time:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo {{.Values.name}} &gt; /package_name</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo {{.Values.additional_field}} &gt; /extra</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>Which would be for example automatically rendered by luet like the following:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo test &gt; /package_name</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo baz &gt; /extra</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>This mechanism can be used in collections as well, and each stanza in <code>packages</code> is used to interpolate each single package.</p> +<h2 id="interpolating-globally">Interpolating globally</h2> +<p>It&rsquo;s possible to interpolate during build phase all the package specs targeted for build with the <code>--values</code> flag, which takes a yaml file of an arbitrary format, if variables are clashing, the yaml supplied in <code>--values</code> takes precedence and overwrite the values of each single <code>definition.yaml</code> file.</p> +<h2 id="shared-templates">Shared templates</h2> +<p>Since luet <code>0.17.5</code> it is possible to share templates across different packages. All templates blocks found inside the <code>templates</code> folder inside the root <code>luet tree</code> of a repository gets templated and shared across all the packages while rendering each compilation spec of the given tree.</p> +<p>Consider the following:</p> +<pre tabindex="0"><code>shared_templates +├── templates +│   └── writefile.yaml +└── test + ├── build.yaml + └── collection.yaml +</code></pre><h4 id="collectionyaml"><code>collection.yaml</code></h4> +<p>We define here two packages with a collection. They will share the same compilation spec to generate two different packages + + + + + +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">packages</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div> + +<small> <i class='fab fa-github'></i> <i>Complete source code: <a target=_blank href="https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/collection.yaml">https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/collection.yaml</a></i> </small> +<hr> +</p> +<h4 id="writefileyaml"><code>writefile.yaml</code></h4> +<p>All the files in the <code>templates</code> folder will get rendered by the template for each package in the tree. We define here a simple block to write out a file from the context which is passed by: + + + + + +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml">{{<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">define &#34;writefile&#34; }}</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo conflict &gt; /foo/{{.}}</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>{{<span style="color:#000">end}}</span></code></pre></div> + +<small> <i class='fab fa-github'></i> <i>Complete source code: <a target=_blank href="https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/templates/writefile.yaml">https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/templates/writefile.yaml</a></i> </small> +<hr> +</p> +<h4 id="buildyaml"><code>build.yaml</code></h4> +<p>Finally the build spec consumes the template block we declared above, passing by the name of the package: + + + + + +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">prelude</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#000">mkdir /foo</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>{{<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">template &#34;writefile&#34; .Values.name }}</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">package_dir</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">/foo</span></code></pre></div> + +<small> <i class='fab fa-github'></i> <i>Complete source code: <a target=_blank href="https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/build.yaml">https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/build.yaml</a></i> </small> +<hr> +</p> +<h2 id="limitations">Limitations</h2> +<p>The <code>finalize.yaml</code> file has access only to the package fields during templating. Extra fields that are present in the <code>definition.yaml</code> file are <em>not</em> accessible during rendering in the <code>finalize.yaml</code> file, but only the package fields (<code>name</code>, <code>version</code>, <code>labels</code>, <code>annotations</code>, &hellip;)</p> +<h2 id="references">References</h2> +<ul> +<li><a href="http://masterminds.github.io/sprig/">Sprig docs</a></li> +<li><a href="https://helm.sh/docs/chart_template_guide/function_list/">Helm Templating functions</a></li> +<li><a href="https://helm.sh/docs/chart_template_guide/variables/">Helm Templating variable</a></li> +</ul> +<h2 id="examples">Examples</h2> +<ul> +<li><a href="https://github.com/mocaccinoOS/mocaccino-musl-universe/tree/master/multi-arch/packages/tar">https://github.com/mocaccinoOS/mocaccino-musl-universe/tree/master/multi-arch/packages/tar</a></li> +</ul> + + + + + + Docs: Collections + https://luet-lab.github.io/docs/docs/concepts/packages/collections/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/packages/collections/ + + + + <p><code>Collections</code> are a special superset of packages. To define a collection, instead of using a <code>definition.yaml</code> file, create a <code>collection.yaml</code> file with a list of packages:</p> + + + + + +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">packages</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div> + +<small> <i class='fab fa-github'></i> <i>Complete source code: <a target=_blank href="https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/collection.yaml">https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/collection.yaml</a></i> </small> +<hr> + +<p>Packages under a collection shares the same <code>build.yaml</code> and <code>finalize.yaml</code>, so a typical package layout can be:</p> +<pre tabindex="0"><code>collection/ + collection.yaml + build.yaml + finalize.yaml + ... additional files in the build context +</code></pre><p>Luet during the build phase, will treat packages of a collection individually. A collection is a way to share the same build process across different packages.</p> +<h2 id="templating">Templating</h2> +<p><a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/templates">The templating mechanism</a> can be used in collections as well, and each stanza in <code>packages</code> is used to interpolate each single package.</p> +<h2 id="examples">Examples</h2> +<ul> +<li><a href="https://github.com/mocaccinoOS/mocaccino-musl-universe/tree/master/multi-arch/packages/entities">https://github.com/mocaccinoOS/mocaccino-musl-universe/tree/master/multi-arch/packages/entities</a></li> +<li><a href="https://github.com/mocaccinoOS/portage-tree/tree/master/multi-arch/packages/groups">https://github.com/mocaccinoOS/portage-tree/tree/master/multi-arch/packages/groups</a></li> +<li><a href="https://github.com/mocaccinoOS/mocaccino-musl-universe/tree/master/multi-arch/packages/X">https://github.com/mocaccinoOS/mocaccino-musl-universe/tree/master/multi-arch/packages/X</a></li> +</ul> + + + + + + diff --git a/docs/concepts/packages/specfile/index.html b/docs/concepts/packages/specfile/index.html new file mode 100644 index 00000000..e23945b0 --- /dev/null +++ b/docs/concepts/packages/specfile/index.html @@ -0,0 +1,921 @@ + + + + + + + + + + + + + + + + + + + + +Specfile | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Specfile

+
Luet specfile syntax
+ +

Specfiles

+

Luet packages are defined by specfiles. Specfiles define the runtime and builtime requirements of a package. There is an hard distinction between runtime and buildtime. A spec is composed at least by the runtime (definition.yaml or a collection.yaml) and the buildtime specification (build.yaml).

+

Luet identifies the package definition by looking at directories that contains a build.yaml and a definition.yaml (or collection.yaml) files. A Luet tree is merely a composition of directories that follows this convention. There is no constriction on either folder naming or hierarchy.

+

Example of a tree folder hierarchy

+
tree distro                                                      
+distro
+├── funtoo              
+│   ├── 1.4
+│   │   ├── build.sh        
+│   │   ├── build.yaml                                             
+│   │   ├── definition.yaml
+│   │   └── finalize.yaml
+│   ├── docker
+│   │   ├── build.yaml
+│   │   ├── definition.yaml
+│   │   └── finalize.yaml
+│   └── meta
+│       └── rpi
+│           └── 0.1
+│               ├── build.yaml
+│               └── definition.yaml
+├── packages
+│   ├── container-diff
+│   │   └── 0.15.0
+│   │       ├── build.yaml
+│   │       └── definition.yaml
+│   └── luet
+│       ├── build.yaml
+│       └── definition.yaml
+├── raspbian
+│   ├── buster
+│   │   ├── build.sh
+│   │   ├── build.yaml
+│   │   ├── definition.yaml
+│   │   └── finalize.yaml
+│   ├── buster-boot
+│   │   ├── build.sh
+│   │   ├── build.yaml
+│   │   ├── definition.yaml
+│   │   └── finalize.yaml
+

Build specs

+

Build specs are defined in build.yaml files. They denote the build-time dependencies and conflicts, together with a definition of the content of the package.

+

Example of a build.yaml file:

+
steps:
+- echo "Luet is awesome" > /awesome
+prelude:
+- echo "nooops!"
+requires:
+- name: "echo"
+  version: ">=1.0"
+conflicts:
+- name: "foo"
+  version: ">=1.0"
+provides:
+- name: "bar"
+  version: ">=1.0"
+env:
+- FOO=bar
+includes:
+- /awesome
+
+unpack: true
+

Building strategies

+

Luet can create packages with different strategies:

+
    +
  • by delta. Luet will analyze the containers differencies to find out which files got added. +You can use the prelude section to exclude certains file during analysis.
  • +
  • by taking a whole container content
  • +
  • by considering a single directory in the build container.
  • +
+

Package by delta

+

By default Luet will analyze the container content and extract any file that gets added to it. The difference is calculated by using the container which is depending on, or either by the container which is created by running the steps in the prelude section of the package build spec:

+
prelude:
+- # do something...
+steps:
+- # real work that should be calculated delta over
+

By omitting the prelude keyword, the delta will be calculated from the parent container where the build will start from.

+

Package by container content

+

Luet can also generate a package content from a container. This is really useful when creating packages that are entire versioned rootfs. To enable this behavior, simply add unpack: true to the build.yaml. This enables the Luet unpacking features, which will extract all the files contained in the container which is built from the prelude and steps fields.

+

To include/exclude single files from it, use the includes and excludes directives.

+

Package by a folder in the final container

+

Similarly, you can tell Luet to create a package from a folder in the build container. To enable this behavior, simply add package_dir: "/path/to/final/dir". +The directory must represent exactly how the files will be ultimately installed from clients, and they will show up in the same layout in the final archive.

+

So for example, to create a package which ships /usr/bin/mybin, we could write:

+
package_dir: "/output"
+steps:
+- mkdir -p /output/usr/bin/
+- echo "fancy stuff" > /output/usr/bin/mybin && chmod +x /output/usr/bin/mybin
+

Build time dependencies

+

A package build spec defines how a package is built. In order to do this, Luet needs to know where to start. Hence a package must declare at least either one of the following:

+
    +
  • an image keyword which tells which Docker image to use as base, or
  • +
  • a list of requires, which are references to other packages available in the tree.
  • +
+

They can’t be both present in the same specfile.

+

To note, it’s not possible to mix package build definitions from different image sources. They must form a unique sub-graph in the build dependency tree.

+

On the other hand it’s possible to have multiple packages depending on a combination of different requires, given they are coming from the same image parent.

+

Excluding/including files explictly

+

Luet can also exclude and include single files or folders from a package by using the excludes and includes keyword respecitvely.

+

Both of them are parsed as a list of Golang regex expressions, and they can be combined together to fine-grainly decide which files should be inside the final artifact. You can refer to the files as they were in the resulting package. So if a package produces a /foo file, and you want to exclude it, you can add it to excludes as /foo.

+

Package source image

+

Luet needs an image to kick-off the build process for each package. This image is being used to run the commands in the steps and prelude, and then the image is processed by the building strategies explained above.

+

The image can be resolved either by:

+
    +
  1. providing a specific image name with image
  2. +
  3. providing a set of package requirements with requires which will be constructed a new image from. The resulting image is an image linked between each other with the FROM field in the Dockerfile following the SAT solver ordering.
  4. +
  5. providing a set of packages to squash their result from requires and by specifying requires_final_images: true.
  6. +
+ + + + +

Difference between requires and requires with requires_final_images: true

+

requires generates a graph from all the images of the specfile referenced inside the list. This means it builds a chain of images that are used to build the packages, e.g.: packageA(image: busybox) -> packageB (requires: A) -> packageC (requires: C). The container which is running your build then inherits it’s parents from a chain of order resolution, provided by the SAT solver.

+

When specifying requires_final_images: true luet builds an artifact for each of the packages listed from their compilation specs and it will later squash them together in a new container image which is then used in the build process to create an artifact.

+

The key difference is about where your build is going to run from. By specifying requires_final_images it will be constructed a new image with the content of each package - while if setting it to false, it will order the images appropriately and link them together with the Dockerfile FROM field. That allows to reuse the same images used to build the packages in the require section - or - create a new one from the result of each package compilation.

+

Keywords

+

Here is a list of the full keyword refereces for the build.yaml file.

+

conflicts

+

(optional) List of packages which it conflicts with in build time. In the same form of requires it is a list of packages that the current one is conflicting with.

+
conflicts:
+- name: "foo"
+  category: "bar"
+  version: "1.0"
+...
+- name: "baz"
+  category: "bar"
+  version: "1.0"
+

See Package concepts for more information on how to represent a package in a Luet tree.

+

copy

+

since luet>=0.15.0

+

(optional) A list of packages/images where to copy files from. It is the Docker multi-stage build equivalent but enhanced with tree hashing resolution.

+

To copy a specific file from a package build container:

+
steps:
+- ...
+prelude:
+- ...
+copy:
+- package: 
+    category: "foo"
+    name: "bar"
+    version: ">=0"
+  source: "/foo"
+  destination: "/bar"
+

Any package that is listed in the section will be compiled beforeahead the package, and the file is available both in prelude and steps.

+

Internally, it’s rendered as COPY --from=package/image:sha /foo /bar

+

To copy a specific file from an external image:

+
steps:
+- ...
+prelude:
+- ...
+copy:
+- image: "buxybox:latest"
+  source: "/foo"
+  destination: "/bar"
+

env

+

(optional) A list of environment variables ( in NAME=value format ) that are expanded in step and in prelude. ( e.g. ${NAME} ).

+
env:
+- PATH=$PATH:/usr/local/go/bin
+- GOPATH=/luetbuild/go
+- GO111MODULE=on
+- CGO_ENABLED=0
+- LDFLAGS="-s -w"
+

excludes

+

(optional) List of golang regexes. They are in full path form (e.g. ^/usr/bin/foo ) and indicates that the files listed shouldn’t be part of the final artifact

+

Wildcards and golang regular expressions are supported. If specified, files which are not matching any of the regular expressions in the list will be excluded in the final package.

+
excludes:
+- ^/etc/shadow
+- ^/etc/os-release
+- ^/etc/gshadow
+

By combining excludes with includes, it’s possible to include certain files while excluding explicitly some others (excludes takes precedence over includes).

+

image

+

(optional/required) Docker image to be used to build the package.

+
image: "busybox"
+

It might be omitted in place of requires, and indicates the image used to build the package. The image will be pulled and used to build the package.

+

includes

+

(optional) List of regular expressions to match files in the resulting package. The path is absolute as it would refer directly to the artifact content.

+

Wildcards and golang regular expressions are supported. If specified, files which are not matching any of the regular expressions in the list will be excluded in the final package.

+
includes:
+- /etc$
+- /etc/lvm$
+- /etc/lvm/.*
+- /usr$
+- /usr/bin$
+- /usr/bin/cc.*
+- /usr/bin/c\+\+.*
+- /usr/bin/cpp.*
+- /usr/bin/g\+\+.*
+

Note: Directories are treated as standard entries, so to include a single file, you need also to explictly include also it’s directory. Consider this example to include /etc/lvm/lvm.conf:

+
includes:
+- /etc$
+- /etc/lvm$
+- /etc/lvm/lvm.conf
+

join

+

since luet>=0.16.0 +to be deprecated in luet>=0.18.0 in favor of requires_final_images

+

(optional/required) List of packages which are used to generate a parent image from.

+

It might be omitted in place of image or requires, and will generate an image which will be used as source of the package from the final packages in the above list. The new image is used to run eventually the package building process and a new artifact can be generated out of it.

+
join:
+- name: "foo"
+  category: "bar"
+  version: "1.0"
+...
+- name: "baz"
+  category: "bar"
+  version: "1.0"
+

See Package concepts for more information on how to represent a package in a Luet tree.

+

Examples

+ +

package_dir

+

(optional) A path relative to the build container where to create the package from.

+

Similarly to unpack, changes the building strategy.

+
steps:
+- mkdir -p /foo/bar/etc/myapp
+- touch /foo/bar/etc/myapp/config
+package_dir: /foo/bar
+

prelude

+

(optional) A list of commands to perform in the build container before building.

+
prelude:
+- |
+   PACKAGE_VERSION=${PACKAGE_VERSION%\+*} && \
+   git clone https://github.com/mudler/yip && cd yip && git checkout "${PACKAGE_VERSION}" -b build   
+

requires

+

(optional/required) List of packages which it depends on.

+

A list of packages that the current package depends on in build time. It might be omitted in place of image, and determines the resolution tree of the package itself. A new image is composed from the packages listed in this section in order to build the package

+
requires:
+- name: "foo"
+  category: "bar"
+  version: "1.0"
+...
+- name: "baz"
+  category: "bar"
+  version: "1.0"
+

See Package concepts for more information on how to represent a package in a Luet tree.

+

requires_final_images

+

since luet>=0.17.0

+

(optional) A boolean flag which instruct luet to use the final images in the requires field.

+

By setting requires_final_images: true in the compilation spec, packages in the requires section will be first compiled, and afterwards the final packages are squashed together in a new image that will be used during build.

+
requires:
+- name: "foo"
+  category: "bar"
+  version: "1.0"
+...
+- name: "baz"
+  category: "bar"
+  version: "1.0"
+
+requires_final_images: true
+

requires_final_images replaces the use of join, which will be deprecated in luet >=0.18.0.

+

step

+

(optional) List of commands to perform in the build container.

+
steps:
+- |
+      cd yip && make build-small && mv yip /usr/bin/yip
+

unpack

+

(optional) Boolean flag. It indicates to use the unpacking strategy while building a package

+
unpack: true
+

It indicates that the package content is the whole container content.

+

Rutime specs

+

Runtime specification are denoted in a definition.yaml or a collection.yaml sibiling file. It identifies the package and the runtime contraints attached to it.

+

definition.yaml:

+
name: "awesome"
+version: "0.1"
+category: "foo"
+requires:
+- name: "echo"
+  version: ">=1.0"
+  category: "bar"
+conflicts:
+- name: "foo"
+  version: "1.0"
+provides:
+- name: "bar"
+  version: "<1.0"
+

A collection.yaml can be used in place of a definition.yaml to identify a set of packages that instead shares a common build.yaml:

+

collection.yaml:

+
packages:
+- name: "awesome"
+  version: "0.1"
+  category: "foo"
+  requires:
+  - name: "echo"
+    version: ">=1.0"
+    category: "bar"
+  conflicts:
+  - name: "foo"
+    version: "1.0"
+  provides:
+  - name: "bar"
+    version: "<1.0"
+- name: "awesome"
+  version: "0.2"
+  category: "foo"
+  requires:
+  - name: "echo"
+    version: ">=1.0"
+    category: "bar"
+  conflicts:
+  - name: "foo"
+    version: "1.0"
+  provides:
+  - name: "bar"
+    version: "<1.0"
+...
+

All the fields (also the ones which are not part of the spec) in the definition.yaml file are available as templating values when rendering the build.yaml file. When running finalizers instead only the fields belonging to the specs are available.

+

Keywords

+

Here is a list of the full keyword refereces

+

annotations

+

(optional) A map of freeform package annotations:

+
annotations:
+  foo: "bar"
+  baz: "test"
+

category

+

(optional) A string containing the category of the package

+
category: "system"
+

conflicts

+

(optional) List of packages which it conflicts with in runtime. In the same form of requires it is a list of packages that the current one is conflicting with.

+
conflicts:
+- name: "foo"
+  category: "bar"
+  version: "1.0"
+...
+- name: "baz"
+  category: "bar"
+  version: "1.0"
+

See Package concepts for more information on how to represent a package in a Luet tree.

+

description

+

(optional) A string indicating the package description

+
name: "foo"
+description: "foo is capable of..."
+

hidden

+

(optional) A boolean indicating whether the package has to be shown or not in the search results (luet search...)

+
hidden: true
+

labels

+

(optional) A map of freeform package labels:

+
labels:
+  foo: "bar"
+  baz: "test"
+

Labels can be used in luet search to find packages by labels, e.g.:

+
$> luet search --by-label foo
+

license

+

(optional) A string indicating the package license type.

+
license: "GPL-3"
+

name

+

(required) A string containing the name of the package

+
name: "foo"
+

provides

+

(optional) List of packages which the current package is providing.

+
conflicts:
+- name: "foo"
+  category: "bar"
+  version: "1.0"
+...
+- name: "baz"
+  category: "bar"
+  version: "1.0"
+

See Package concepts for more information on how to represent a package in a Luet tree.

+

requires

+

(optional) List of packages which it depends on in runtime.

+

A list of packages that the current package depends on in runtime. The determines the resolution tree of the package itself.

+
requires:
+- name: "foo"
+  category: "bar"
+  version: "1.0"
+...
+- name: "baz"
+  category: "bar"
+  version: "1.0"
+

See Package concepts for more information on how to represent a package in a Luet tree.

+

uri

+

(optional) A list of URI relative to the package ( e.g. the official project pages, wikis, README, etc )

+
uri:
+- "http://www.mocaccino.org"
+- ...
+

version

+

(required) A string containing the version of the package

+
version: "1.0"
+

Refering to packages from the CLI

+

All the luet commands which takes a package as argument, respect the following syntax notation:

+
    +
  • cat/name: will default to selecting any available package
  • +
  • =cat/name: will default to gentoo parsing with regexp so also =cat/name-1.1 works
  • +
  • cat/name@version: will select the specific version wanted ( e.g. cat/name@1.1 ) but can also include ranges as well cat/name@>=1.1
  • +
  • name: just name, category is omitted and considered empty
  • +
+

Finalizers

+

Finalizers are denoted in a finalize.yaml file, which is a sibiling of definition.yaml and build.yaml file. It contains a list of commands that finalize the package when it is installed in the machine.

+

finalize.yaml:

+
install:
+- rc-update add docker default
+

Keywords

+
    +
  • install: List of commands to run in the host machine. Failures are eventually ignored, but will be reported and luet will exit non-zero in such case.
  • +
+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/concepts/packages/templates/index.html b/docs/concepts/packages/templates/index.html new file mode 100644 index 00000000..e5997e2a --- /dev/null +++ b/docs/concepts/packages/templates/index.html @@ -0,0 +1,581 @@ + + + + + + + + + + + + + + + + + + + + +Templated packages | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Templated packages

+
Use templates to fine tune build specs
+ +

Luet supports the sprig rendering engine template, like helm. It’s being used to interpolate build.yaml and finalize.yaml files before their execution. The following document assumes you are familiar with the helm templating.

+

The build.yaml and finalize.yaml files are rendered during build time, and it’s possible to use the helm templating syntax inside such files. The definition.yaml file will be used to interpolate templating values available in build.yaml

+

Given the following definition.yaml:

+
name: "test"
+category: "foo"
+version: "1.1"
+
+additional_field: "baz"
+

A build.yaml can look like the following, and interpolates it’s values during build time:

+
image: ...
+
+steps:
+- echo {{.Values.name}} > /package_name
+- echo {{.Values.additional_field}} > /extra
+
+

Which would be for example automatically rendered by luet like the following:

+

+image: ...
+
+steps:
+- echo test > /package_name
+- echo baz > /extra
+
+

This mechanism can be used in collections as well, and each stanza in packages is used to interpolate each single package.

+

Interpolating globally

+

It’s possible to interpolate during build phase all the package specs targeted for build with the --values flag, which takes a yaml file of an arbitrary format, if variables are clashing, the yaml supplied in --values takes precedence and overwrite the values of each single definition.yaml file.

+

Shared templates

+

Since luet 0.17.5 it is possible to share templates across different packages. All templates blocks found inside the templates folder inside the root luet tree of a repository gets templated and shared across all the packages while rendering each compilation spec of the given tree.

+

Consider the following:

+
shared_templates
+├── templates
+│   └── writefile.yaml
+└── test
+    ├── build.yaml
+    └── collection.yaml
+

collection.yaml

+

We define here two packages with a collection. They will share the same compilation spec to generate two different packages + + + + + +

packages:
+- category: "test"
+  name: "foo"
+  version: "1.0"
+- category: "test"
+  name: "bar"
+  version: "1.0"
+
+ + Complete source code: https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/collection.yaml +
+

+

writefile.yaml

+

All the files in the templates folder will get rendered by the template for each package in the tree. We define here a simple block to write out a file from the context which is passed by: + + + + + +

{{ define "writefile" }}
+- echo conflict > /foo/{{.}}
+{{end}}
+ + Complete source code: https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/templates/writefile.yaml +
+

+

build.yaml

+

Finally the build spec consumes the template block we declared above, passing by the name of the package: + + + + + +

image: "alpine"
+prelude:
+  - mkdir /foo
+steps:
+{{ template "writefile" .Values.name }}
+package_dir: /foo
+ + Complete source code: https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/build.yaml +
+

+

Limitations

+

The finalize.yaml file has access only to the package fields during templating. Extra fields that are present in the definition.yaml file are not accessible during rendering in the finalize.yaml file, but only the package fields (name, version, labels, annotations, …)

+

References

+ +

Examples

+ + + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/concepts/plugins-and-extensions/index.html b/docs/concepts/plugins-and-extensions/index.html new file mode 100644 index 00000000..2a751f59 --- /dev/null +++ b/docs/concepts/plugins-and-extensions/index.html @@ -0,0 +1,575 @@ + + + + + + + + + + + + + + + + + + + + + +Plugins and Extensions | Luet + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Plugins and Extensions

+
Extend luet with plugins and extensions
+ +

Luet can be extended in 2 ways by extensions and plugins.

+

Before you begin

+

You need to have a working luet binary installed.

+

Extensions

+

Extensions expand Luet featureset horizontally, so for example, “luet geniso” will allow you to build an iso using luet, without this needing to be part of the luet core.

+

An Extension is nothing more than a standalone executable file, whose name begins with luet-. To install an extension, simply move its executable file to anywhere on your system PATH.

+

All the plugins will be accessible to luet as luet pluginname

+

Writing an Extension

+

You can write an extension in any programming language or script that allows you to write command-line commands.

+

Executables receive the inherited environment from luet. An extension determines which command path it wishes to implement based on its name. For example, a plugin wanting to provide a new command luet foo, would simply be named luet-foo, and live somewhere in your PATH.

+

Example Extension

+
#!/bin/bash
+
+if [[ "$1" == "help" ]]
+then
+    echo "Extension help"
+    exit 0
+fi
+
+if [[ "$1" == "run" ]]
+then
+    # do something interesting
+fi
+
+echo "I am an Extension named luet-foo"
+
+

Using an Extension

+

To use the above extension, simply make it executable:

+
$ sudo chmod +x ./luet-foo
+

and place it anywhere in your PATH:

+
$ sudo mv ./luet-foo /usr/local/bin
+

You may now invoke your extension as a luet command:

+
$ luet foo
+I am an Extension named luet-foo
+

All args and flags are passed as-is to the executable:

+
$ luet foo help
+
+Extension help
+

Plugins

+

Plugins instead are expanding Luet vertically by hooking into internal events. Plugins and Extensions can be written in any language, bash included! Luet uses go-pluggable so it can dispatch events to external binaries.

+

Similarly to Extensions, a Plugin is nothing more than a standalone executable file, but without any special prefix. To install a plugin, simply move its executable file to anywhere on your system PATH.

+

Differently from Extensions, they are not available from the CLI and cannot be invoked directly by the user, instead they are called by Luet during its lifecycle.

+

Writing a Plugin

+

You can write a plugin in any programming language or script.

+

The first argument that is passed to a plugin will always be the event that was emitted by Luet in its lifecycle. You can see all the events available here. The second argument, is a JSON encoded payload of the object that Luet is emitting with the event. The object(s) may vary depending on the emitted event.

+

The output of the plugin (stdout) will be parsed as JSON. Every plugin must return a valid JSON at the end of its execution, or it will be marked as failed and stops luet further execution. See also the go-pluggable README.

+

The returning payload should be in the following form:

+
{ "state": "", "data": "data", "error": ""}
+

By returning a json with the error field not empty, it will make fail the overall execution.

+

Example Plugin

+
#!/bin/bash
+echo "$1" >> /tmp/event.txt
+echo "$2" >> /tmp/payload.txt
+
+echo "{}"
+
+

Using a plugin

+

To use the above plugin, simply make it executable:

+
$ sudo chmod +x ./test-foo
+

and place it anywhere in your PATH:

+
$ sudo mv ./test-foo /usr/local/bin
+

Now, when running luet, add --plugin test-foo:

+

+$ luet --plugin test-foo install -y foopackage
+
+

And check /tmp/event.txt to see the event fired and /tmp/payload.txt to check the payloads that were emitted by Luet.

+

Concrete example

+

A plugin that prints the images that are being built in /tmp/exec.log:

+
#!/bin/bash
+exec >> /tmp/exec.log
+exec 2>&1
+event="$1"
+payload="$2"
+if [ "$event" == "image.post.build" ]; then
+  image=$(echo "$payload" | jq -r .data | jq -r .ImageName )
+    echo "{ \"data\": \"$image built\" }"
+else
+    echo "{}"
+fi
+
+
+
+ + + + + + + + + +
+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/concepts/plugins-and-extensions/index.xml b/docs/concepts/plugins-and-extensions/index.xml new file mode 100644 index 00000000..bbec1042 --- /dev/null +++ b/docs/concepts/plugins-and-extensions/index.xml @@ -0,0 +1,17 @@ + + + Luet – Plugins and Extensions + https://luet-lab.github.io/docs/docs/concepts/plugins-and-extensions/ + Recent content in Plugins and Extensions on Luet + Hugo -- gohugo.io + + + + + + + + + + + diff --git a/docs/contribution-guidelines/index.html b/docs/contribution-guidelines/index.html new file mode 100644 index 00000000..400247a3 --- /dev/null +++ b/docs/contribution-guidelines/index.html @@ -0,0 +1,528 @@ + + + + + + + + + + + + + + + + + + + + +Contributing | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Contributing

+ + +

Contributing to Luet

+

Contribution guidelines for the Luet project are on the Github repository. Here you can find some heads up for contributing to the documentation website.

+

Contributing to the Docs website

+

We Develop with Github

+

We use github to host code, to track issues and feature requests, as well as accept pull requests.

+

We use Hugo to format and generate our website, the +Docsy theme for styling and site structure, +and Github Actions to manage the deployment of the site. +Hugo is an open-source static site generator that provides us with templates, +content organisation in a standard directory structure, and a website generation +engine. You write the pages in Markdown (or HTML if you want), and Hugo wraps them up into a website.

+

All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. Consult +GitHub Help for more +information on using pull requests.

+

Any contributions you make will be under the Software License of the repository

+

In short, when you submit code changes, your submissions are understood to be under the same License that covers the project. Feel free to contact the maintainers if that’s a concern.

+

Updating a single page

+

If you’ve just spotted something you’d like to change while using the docs, Docsy has a shortcut for you:

+
    +
  1. Click Edit this page in the top right hand corner of the page you want to modify.
  2. +
  3. If you don’t already have an up to date fork of the project repo, you are prompted to get one - click Fork this repository and propose changes or Update your Fork to get an up to date version of the project to edit. The appropriate page in your fork is displayed in edit mode.
  4. +
+

Quick start with a local checkout

+

Here’s a quick guide to updating the docs with a git local checkout. It assumes you’re familiar with the +GitHub workflow and you’re happy to use the automated preview of your doc +updates:

+
    +
  1. Fork the the Docs repo on GitHub.
  2. +
  3. Make your changes, to see the preview run make serve and browse to localhost:1313
  4. +
  5. If you’re not yet ready for a review, add “WIP” to the PR name to indicate +it’s a work in progress.
  6. +
  7. Continue updating your doc and pushing your changes until you’re happy with +the content.
  8. +
  9. When you’re ready for a review, add a comment to the PR, and remove any +“WIP” markers.
  10. +
  11. When you are satisfied send a pull request (PR).
  12. +
+

License

+

By contributing, you agree that your contributions will be licensed under the project Licenses.

+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/getting-started/index.html b/docs/getting-started/index.html new file mode 100644 index 00000000..05efb607 --- /dev/null +++ b/docs/getting-started/index.html @@ -0,0 +1,592 @@ + + + + + + + + + + + + + + + + + + + + + +Getting Started | Luet + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Getting Started

+
First steps with Luet
+ +

Prerequisites

+

No dependencies. For building packages see the Build Packages section

+

Get Luet

+

From release

+

Just grab a release from the release page on GitHub. The binaries are statically compiled.

+

Or you can install Luet also with a single command:

+
curl https://get.mocaccino.org/luet/get_luet_root.sh | sudo sh
+

Building Luet from source

+

Requirements:

+
    +
  • Golang installed in your system.
  • +
  • make
  • +
+
$> git clone https://github.com/mudler/luet
+$> cd luet
+$> make build # or just go build
+

Install it as a system package

+

In the following section we will see how to install luet with luet itself. We will use a transient luet version that we are going to throw away right after we install it in the system.

+
# Get a luet release. It will be used to install luet in your system
+wget https://github.com/mudler/luet/releases/download/0.8.3/luet-0.8.3-linux-amd64 -O luet
+chmod +x luet
+
+# Creates the luet configuration file and add the luet-index repository.
+# The luet-index repository contains a collection of repositories which are 
+# installable and tracked in your system as standard packages.
+cat > .luet.yaml <<EOF
+repositories:
+- name: "mocaccino-repository-index"
+  description: "MocaccinoOS Repository index"
+  type: "http"
+  enable: true
+  cached: true
+  priority: 1
+  urls:
+  - "https://raw.githubusercontent.com/mocaccinoOS/repository-index/gh-pages"
+EOF
+
+# Install the official luet repository to get always the latest luet version
+./luet install repository/luet
+
+# Install luet (with luet) in your system
+./luet install system/luet
+
+# Remove the temporary luet used for bootstrapping
+rm -rf luet
+
+# Copy over the config file to your system
+mkdir -p /etc/luet
+mv .luet.yaml /etc/luet/luet.yaml
+

Configuration

+

Luet stores its configuration files in /etc/luet. If you wish to override its default settings, create a file /etc/luet/luet.yaml.

+

A example of a luet.yaml file can be found here.

+

There are a bunch of configuration settings available, but the most relevant are:

+
logging:
+  color: true # Enable/Disable colored output
+  enable_emoji: true # Enable/Disable emoji from output
+general:
+  debug: false # Enable/Disable debug
+system:
+  rootfs: "/" # What's our rootfs. Luet can install packages outside of "/"
+  database_path: "/var/db/luet" # Where to store DB files
+  database_engine: "boltdb"
+  tmpdir_base: "/var/tmp/luet" # The temporary directory to be used
+

Adding repositories

+

To add repositories, you can either add a repositories stanza in your /etc/luet/luet.yaml or either add one or more yaml files in /etc/luet/repos.conf.d/.

+

Configuration in /etc/luet/luet.yaml

+
logging:
+  color: true # Enable/Disable colored output
+  enable_emoji: true # Enable/Disable emoji from output
+general:
+  debug: false # Enable/Disable debug
+system:
+  rootfs: "/" # What's our rootfs. Luet can install packages outside of "/"
+  database_path: "/var/db/luet" # Where to store DB files
+  database_engine: "boltdb"
+  tmpdir_base: "/var/tmp/luet" # The temporary directory to be used
+repositories:
+- name: "some-repository-name" # Repository name
+  description: "A beautiful description"
+  type: "http" # Repository type, disk or http are supported (disk for local path)
+  enable: true # Enable/Disable repo
+  cached: true # Enable cache for repository
+  priority: 3 # Cache priority
+  urls: # Repository URLs
+    - "...."
+

Configuration in /etc/luet/repos.conf.d/

+

A repository file can be for example:

+
name: "..." # Repository name
+description: "..."
+type: "http" # Repository type, disk or http are supported (disk for local path)
+enable: true # Enable/Disable repo
+cached: true # Enable cache for repository
+priority: 3 # Cache priority
+urls: # Repository URLs
+  - "..."
+

There is available a collection of repositories, which is containing a list of repositories that can be installed in the system with luet install.

+

If you installed Luet from the curl command, you just need to run luet search repository to see a list of all the available repository, and you can install them singularly by running luet install repository/<name>. Otherwise, add the repository stanzas you need to /etc/luet/luet.yaml.

+ +
+ + + + + + + + + +
+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/getting-started/index.xml b/docs/getting-started/index.xml new file mode 100644 index 00000000..3921f6b7 --- /dev/null +++ b/docs/getting-started/index.xml @@ -0,0 +1,17 @@ + + + Luet – Getting Started + https://luet-lab.github.io/docs/docs/getting-started/ + Recent content in Getting Started on Luet + Hugo -- gohugo.io + + + + + + + + + + + diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..7d5ac250 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,519 @@ + + + + + + + + + + + + + + + + + + + + + +Documentation | Luet + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Documentation

+ + +

Luet is a Package Manager based on containers. It provides an abstraction layer over container specfile format, enhancing the image resolution process of open container inititative (OCI) runtimes with boolean satisfiability problem (SAT) solving techniques.

+

Luet can be used to build packages, container images, as well as to manage and distribute installations of derived packages locally.

+

Allows to apply semver constraints to Image dependencies, treating it as a classical CSP.

+ + +
+ + + + + + + + +
+ + +
+
+ Getting Started +
+

First steps with Luet

+
+ + +
+
+ Concepts +
+

Documentation references

+
+ + +
+
+ Tutorials +
+

Howtos, Cookbooks

+
+ + +
+
+ Resources +
+

Luet examples, resources, API reference

+
+ + +
+
+ Contributing +
+

+
+ + +
+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/index.xml b/docs/index.xml new file mode 100644 index 00000000..6abeb7cb --- /dev/null +++ b/docs/index.xml @@ -0,0 +1,1495 @@ + + + Luet – Documentation + https://luet-lab.github.io/docs/docs/ + Recent content in Documentation on Luet + Hugo -- gohugo.io + + + + + + + + + + + Docs: Building packages + https://luet-lab.github.io/docs/docs/concepts/overview/build_packages/ + Thu, 05 Jan 2017 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/overview/build_packages/ + + + + <h2 id="prerequisistes">Prerequisistes</h2> +<p>Luet currently supports <a href="https://www.docker.com/">Docker</a> and <a href="https://github.com/genuinetools/img">Img</a> as backends to build packages. Both of them can be used and switched in runtime with the <code>--backend</code> option, so either one of them must be present in the host system.</p> +<h3 id="docker">Docker</h3> +<p>Docker is the (less) experimental Luet engine supported. Be sure to have Docker installed and the daemon running. The user running <code>luet</code> commands needs the corresponding permissions to run the <code>docker</code> executable, and to connect to a <code>docker</code> daemon. The only feature needed by the daemon is the ability to build images, so it fully supports remote daemon as well (this can be specified with the <code>DOCKER_HOST</code> environment variable, that is respected by <code>luet</code>)</p> +<h3 id="img">Img</h3> +<p>Luet supports <a href="https://github.com/genuinetools/img">Img</a>. To use it, simply install it in your system, and while running <code>luet build</code>, you can switch the backend by providing it as a parameter: <code>luet build --backend img</code>. For small packages it is particularly powerful, as it doesn&rsquo;t require any docker daemon running in the host.</p> +<h3 id="building-packages-on-kubernetes">Building packages on Kubernetes</h3> +<p>Luet and img can be used together to orchestrate package builds also on kubernetes. There is available an experimental <a href="https://github.com/mudler/luet-k8s">Kubernetes CRD for Luet</a> which allows to build packages seamelessly in Kubernetes and push package artifacts to an S3 Compatible object storage (e.g. Minio).</p> +<h2 id="building-packages">Building packages</h2> +<p><img src="https://luet-lab.github.io/docs/docs/tree.jpg" alt="Build packages"></p> +<p>Luet provides an abstraction layer on top of the container image layer to make the package a first class construct. A package definition and all its dependencies are translated by Luet to Dockerfiles which can then be built anywhere that docker runs.</p> +<p>To resolve the dependency tree Luet uses a SAT solver and no database. It is responsible for calculating the dependencies of a package and to prevent conflicts. The Luet core is still young, but it has a comprehensive test suite that we use to validate any future changes.</p> +<p>Building a package with Luet requires only a <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile">definition</a>. This definition can be self-contained and be only composed of one <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile">specfile</a>, or a group of them, forming a Luet tree. For more complex use-cases, see <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/collections">collections</a>.</p> +<p>Run <code>luet build --help</code> to get more help for each parameter.</p> +<p>Build accepts a list of packages to build, which syntax is in the <code>category/name-version</code> notation. See also <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile/#refering-to-packages-from-the-cli">specfile documentation page</a> to see how to express packages from the CLI.</p> +<h2 id="environmental-variables">Environmental variables</h2> +<p>Luet builds passes its environment variable at the engine which is called during build, so for example the environment variable <code>DOCKER_HOST</code> or <code>DOCKER_BUILDKIT</code> can be setted.</p> +<p>Every argument from the CLI can be setted via environment variable too with a <code>LUET_</code> prefix, for instance the flag <code>--clean</code>, can be setted via environment with <code>LUET_CLEAN</code>, <code>--privileged</code> can be enabled with <code>LUET_PRIVILEGED</code> and so on.</p> +<h2 id="supported-compression-format">Supported compression format</h2> +<p>At the moment, <code>luet</code> can compress packages and tree with <code>zstd</code> and <code>gzip</code>. For example:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">luet build --compression zstd ... +</code></pre></div><p>Will output package compressed in the zstd format.</p> +<p>See the <code>--help</code> of <code>create-repo</code> and <code>build</code> to learn all the available options.</p> +<h2 id="example">Example</h2> +<p>A <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile">package definition</a> is composed of a <code>build.yaml</code> and a sibiling <code>definition.yaml</code>.</p> +<p>In the following example, we are creating a dummy package (<code>bar/foo</code>). Which ships one file only, <code>/foo</code></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$&gt; <span style="color:#8f5902;font-style:italic"># put yourself in some workdir</span> + +$~/workdir&gt; mkdir package + +$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package/build.yaml +</span><span style="color:#4e9a06">image: busybox +</span><span style="color:#4e9a06">steps: +</span><span style="color:#4e9a06">- echo &#34;foo=bar&#34; &gt; /foo +</span><span style="color:#4e9a06">EOF</span> + +$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package/definition.yaml +</span><span style="color:#4e9a06">name: &#34;foo&#34; +</span><span style="color:#4e9a06">version: &#34;0.1&#34; +</span><span style="color:#4e9a06">category: &#34;bar&#34; +</span><span style="color:#4e9a06">EOF</span> + +</code></pre></div><p>To build it, simply run <code>luet build bar/foo</code> or <code>luet build --all</code> to build all the packages in the current directory:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$&gt; luet build --all + +📦 Selecting foo 0.1 +📦 Compiling foo version 0.1 .... ☕ +🐋 Downloading image luet/cache-foo-bar-0.1-builder +🐋 Downloading image luet/cache-foo-bar-0.1 +📦 foo Generating 🐋 definition <span style="color:#204a87;font-weight:bold">for</span> builder image from busybox +🐋 Building image luet/cache-foo-bar-0.1-builder +🐋 Building image luet/cache-foo-bar-0.1-builder <span style="color:#204a87;font-weight:bold">done</span> + Sending build context to Docker daemon 4.096kB + ... + +</code></pre></div><p>Luet &ldquo;trees&rdquo; are just a group of specfiles, in the above example, our tree was the current directory. You can also specify a directory with the <code>--tree</code> option. Luet doesn&rsquo;t enforce any tree layout, so they can be nested at any level. The only rule of thumb is that a <code>build.yaml</code> file needs to have either a <code>definition.yaml</code> or a <code>collection.yaml</code> file next to it.</p> +<h2 id="nesting-dependencies">Nesting dependencies</h2> +<p>In the example above we have created a package from a <code>delta</code>. Luet by default creates packages by analyzing the differences between the generated containers, and extracts the differences as archive, the resulting files then are compressed and can be consumed later on by <code>luet install</code>.</p> +<p>Luet can create packages from different <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile/#building-strategies">building strategies</a>: by delta, by taking a whole container content, or by considering a single directory in the build container.</p> +<p>Besides that, <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile/#build-time-dependencies">a package can reference a strict dependency on others</a>.</p> +<h3 id="example-1">Example</h3> +<p>Let&rsquo;s extend the above example with two packages which depends on it during the build phase.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$~/workdir&gt; mkdir package2 + +$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package2/build.yaml +</span><span style="color:#4e9a06">requires: +</span><span style="color:#4e9a06">- name: &#34;foo&#34; +</span><span style="color:#4e9a06"> category: &#34;bar&#34; +</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34; +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06">steps: +</span><span style="color:#4e9a06">- source /foo &amp;&amp; echo &#34;$foo&#34; &gt; /bar +</span><span style="color:#4e9a06">EOF</span> + +$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package2/definition.yaml +</span><span style="color:#4e9a06">name: &#34;ineedfoo&#34; +</span><span style="color:#4e9a06">version: &#34;0.1&#34; +</span><span style="color:#4e9a06">category: &#34;bar&#34; +</span><span style="color:#4e9a06">EOF</span> + + +$~/workdir&gt; mkdir package3 + +$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package3/build.yaml +</span><span style="color:#4e9a06">requires: +</span><span style="color:#4e9a06">- name: &#34;foo&#34; +</span><span style="color:#4e9a06"> category: &#34;bar&#34; +</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34; +</span><span style="color:#4e9a06">- name: &#34;ineedfoo&#34; +</span><span style="color:#4e9a06"> category: &#34;bar&#34; +</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34; +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06">steps: +</span><span style="color:#4e9a06">- source /foo &amp;&amp; echo &#34;$foo&#34; &gt; /ineedboth +</span><span style="color:#4e9a06">- cat /bar &gt; /bar +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06">EOF</span> + +$~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; package3/definition.yaml +</span><span style="color:#4e9a06">name: &#34;ineedfooandbar&#34; +</span><span style="color:#4e9a06">version: &#34;0.1&#34; +</span><span style="color:#4e9a06">category: &#34;bar&#34; +</span><span style="color:#4e9a06">EOF</span> + +</code></pre></div><p>To build, run again:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$&gt; luet build --all +</code></pre></div><p>As we can see, now Luet generated 3 packages, <code>bar/foo</code>, <code>bar/ineedfoo</code> and <code>bar/ineedfooandbar</code>. They aren&rsquo;t doing anything special than just shipping text files, this is an illustrative example on how build requirements can be combined to form new packages:</p> +<p><code>bar/ineedfooandbar</code> depends on both <code>bar/ineedfoo</code> and <code>bar/foo</code> during build-time, while <code>bar/foo</code> uses a docker image as a build base.</p> +<p>See the <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile/#building-strategies">package definition documentation page</a> for more details on how to instruct the Luet compiler to build packages with different strategies.</p> +<h2 id="caching-docker-images">Caching docker images</h2> +<p>Luet can push and pull the docker images that are being generated during the build process. A tree is represented by a single docker image, and each package can have one or more tags attached to it.</p> +<p>To push automatically docker images that are built, use the <code>--push</code> option, to pull, use the <code>--pull</code> option. An image repository can be specified with <code>--image-repository</code> flag, and can include also the remote registries where the images are pushed to.</p> +<p>Luet doesn&rsquo;t handle login to registries, so that has to be handled separately with <code>docker login</code> or <code>img login</code> before the build process starts.</p> +<h3 id="build-faster">Build faster</h3> +<p>When packages are cached, for iterating locally it&rsquo;s particularly useful to jump straight to the image that you want to build. You can use <code>--only-target-package</code> to jump directly to the image you are interested in. Luet will take care of checking if the images are present in the remote registry, and would build them if any of those are missing.</p> +<h2 id="notes">Notes</h2> +<ul> +<li>All the files which are next to a <code>build.yaml</code> are copied in the container which is running your build, so they are always accessible during build time.</li> +<li>If you notice errors about disk space, mind to set the <code>TMPDIR</code> env variable to a different folder. By default luet respects the O.S. default (which in the majority of system is <code>/tmp</code>).</li> +</ul> + + + + + + Docs: Hello world! + https://luet-lab.github.io/docs/docs/tutorials/hello_world/ + Wed, 04 Jan 2017 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/tutorials/hello_world/ + + + + <p>This article will guide you to build your first package with Luet! +For this purpose, we have picked a real-world example: <a href="https://github.com/gogs/gogs">gogs</a> which is a &ldquo;painless self-hosted Git service&rdquo;, an open-source alternative to Github.</p> +<p>Gogs is written in Golang, and we need a working Golang version in order to build it.</p> +<p>Here you can see a live recorded session of this tutorial:</p> +<script id="asciicast-388348" src="https://asciinema.org/a/388348.js" data-autoplay="true" data-size="small" data-cols="120" data-rows="40" async></script> +<h1 id="define-a-luet-tree">Define a Luet tree</h1> +<p>Everything starts from a Luet tree. A Luet tree is just a directory containing one (or more) Luet specfile, here on we assume that you are working in a dedicated folder (e.g. <code>~/demo</code>) in your system.</p> +<p>Let&rsquo;s create then a package that will be our base to build other packages from now on, we have picked <code>busybox</code> here - it is really small and enough for our purpose.</p> +<h2 id="busybox">busybox</h2> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">mkdir busybox +</code></pre></div><p>Let&rsquo;s now write the build specification, which is just containing the image tag that we are referencing to</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; busybox/build.yaml +</span><span style="color:#4e9a06">image: &#34;busybox:{{.Values.version}}-glibc&#34; +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><p>Now, lets write the <code>definition.yaml</code>, which contains the metadata information about our package ( e.g. how we refer to it with luet, the version, and so on )</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; busybox/definition.yaml +</span><span style="color:#4e9a06">category: &#34;distro&#34; +</span><span style="color:#4e9a06">name: &#34;busybox&#34; +</span><span style="color:#4e9a06">version: &#34;1.33.0&#34; +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><h2 id="golang">golang</h2> +<p>We need now golang in order to build <code>gogs</code>. Let&rsquo;s declare then a golang package:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">mkdir golang +</code></pre></div><p>And a build specfile, which is simply fetch golang from <a href="https://golang.org">https://golang.org</a> and installing it in the busybox container:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; golang/build.yaml +</span><span style="color:#4e9a06">requires: +</span><span style="color:#4e9a06">- category: &#34;distro&#34; +</span><span style="color:#4e9a06"> name: &#34;busybox&#34; +</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34; +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06">prelude: +</span><span style="color:#4e9a06">- wget https://golang.org/dl/go{{.Values.version}}.linux-{{.Values.arch}}.tar.gz -O golang.tar.gz +</span><span style="color:#4e9a06">- mkdir /usr/local +</span><span style="color:#4e9a06">steps: +</span><span style="color:#4e9a06">- tar -C /usr/local -xzf golang.tar.gz +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><p>Note how we <code>require</code> busybox. The Golang container will now be based from busybox, and the <code>prelude</code> and <code>steps</code> fields will be executed in that context.</p> +<p>And finally let&rsquo;s write the golang metadata files, so we can refer to it from other packages</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; golang/definition.yaml +</span><span style="color:#4e9a06">name: &#34;go&#34; +</span><span style="color:#4e9a06">category: &#34;dev-lang&#34; +</span><span style="color:#4e9a06">version: &#34;1.15.6&#34; +</span><span style="color:#4e9a06">arch: &#34;amd64&#34; +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><h2 id="gogs">gogs</h2> +<p>Finally we can write the gogs package definition!</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">mkdir gogs +</code></pre></div><p>The build specfile, will just fetch the <code>gogs</code> sources at a given version (specified in the <code>definition.yaml</code>) and build the sources with go:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;&#39;EOF&#39; &gt; gogs/build.yaml +</span><span style="color:#4e9a06">requires: +</span><span style="color:#4e9a06">- category: &#34;dev-lang&#34; +</span><span style="color:#4e9a06"> name: &#34;go&#34; +</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34; +</span><span style="color:#4e9a06">env: +</span><span style="color:#4e9a06">- GOPATH=&#34;/go&#34; +</span><span style="color:#4e9a06">- GOGSPATH=&#34;$GOPATH/src/github.com/gogs/gogs&#34; +</span><span style="color:#4e9a06">- PATH=$PATH:/usr/local/go/bin +</span><span style="color:#4e9a06">- CGO_ENABLED=0 +</span><span style="color:#4e9a06">prelude: +</span><span style="color:#4e9a06">- mkdir -p $GOPATH/src/github.com/gogs +</span><span style="color:#4e9a06">- wget https://github.com/gogs/gogs/archive/v{{.Values.version}}.tar.gz -O - | tar -xzf - -C ./ &amp;&amp; mv gogs-{{.Values.version}} $GOGSPATH +</span><span style="color:#4e9a06">steps: +</span><span style="color:#4e9a06">- mkdir /usr/bin +</span><span style="color:#4e9a06">- cd $GOGSPATH &amp;&amp; go build &amp;&amp; mv gogs /usr/bin/gogs +</span><span style="color:#4e9a06">excludes: +</span><span style="color:#4e9a06"># Cache generated by Golang +</span><span style="color:#4e9a06">- ^/root +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><p>And the metadata, in this way we can refer to gogs in a Luet tree:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; gogs/definition.yaml +</span><span style="color:#4e9a06">category: &#34;dev-vcs&#34; +</span><span style="color:#4e9a06">name: &#34;gogs&#34; +</span><span style="color:#4e9a06">version: &#34;0.11.91&#34; +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><h1 id="build-packages">Build packages</h1> +<p>The simplest and mostly immediate way to build packages, is running <code>luet build &lt;packagename&gt;</code> in the same folder you have your Luet tree.</p> +<p>In this case, to build gogs and its deps, we can do:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">luet build dev-vcs/gogs +</code></pre></div><p>And that&rsquo;s it! you will find the package archives in <code>build/</code> in the same folder where you started the command.</p> +<p>You will see that Luet generates not only archives with the file resulting to your builds, but it will also generate metadata files (ending with <code>.metadata.yaml</code>) that contains additional metadata information about your build and the package itself (e.g. checksums).</p> +<p>You can use tools like <a href="https://github.com/mikefarah/yq">yq</a> to inspect those:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">yq r build/gogs-dev-vcs-0.11.91.metadata.yaml checksums +</code></pre></div><p>Now if you want to consume the artifacts just built with <code>luet install</code>, you can create a repository with <code>luet create-repo</code>.</p> + + + + + + Docs: Creating Luet repositories + https://luet-lab.github.io/docs/docs/concepts/overview/repositories/ + Thu, 05 Jan 2017 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/overview/repositories/ + + + + <p>After a set of packages has been built, a repository must be created in order to make them accessible by Luet clients. A Repository can be served either local files or via http(s) (at the moment of writing). Luet, by default, supports multiple-repositories with priorities.</p> +<h2 id="create-a-repository">Create a repository</h2> +<p>After issuing a <code>luet build</code>, the built packages are present in the output build directory. The <code>create-repo</code> step is needed to generate a portable tree, which is read by the clients, and a <code>repository.yaml</code> which contains the repository metadata.</p> +<p>Note that the output of <code>create-repo</code> is <em>additive</em> so it integrates with the current build content. The repository is composed by the packages generated by the <code>build</code> command (or <code>pack</code>) and the <code>create-repo</code> generated metadata.</p> +<h3 id="flags">Flags</h3> +<p>Some of the relevant flags for <code>create-repo</code> are:</p> +<ul> +<li><strong>&ndash;descr</strong>: Repository description</li> +<li><strong>&ndash;name</strong>: Repository name</li> +<li><strong>&ndash;output</strong>: Metadata output folder (while a different path can be specified, it&rsquo;s prefered to output the metadata files directly to the package directory).This most of the time matches the packages path for convenience.</li> +<li><strong>&ndash;packages</strong>: Directory where built packages are stored. This most of the time is also the output path.</li> +<li><strong>&ndash;reset-revision</strong>: Reset the repository revision number</li> +<li><strong>&ndash;tree-path</strong>: Specify a custom name for the tree path. (Defaults to tree.tar)</li> +<li><strong>&ndash;tree-compression</strong>: Specify a compression algorithm for the tree. (Available: gzip, Defaults: none)</li> +<li><strong>&ndash;tree</strong>: Path of the tree which was used to generate the packages and holds package metadatas</li> +<li><strong>&ndash;type</strong>: Repository type (http/local). It is just descriptive, the clients will be able to consume the repo in whatsoever way it is served.</li> +<li><strong>&ndash;urls</strong>: List of URIS where the repository is available</li> +</ul> +<p>See <code>luet create-repo --help</code> for a full description.</p> +<h2 id="example">Example</h2> +<p>Build a package and generate the repository metadata:</p> +<pre tabindex="0"><code>$&gt; mkdir package + +$&gt; cat &lt;&lt;EOF &gt; package/build.yaml +image: busybox +steps: +- echo &quot;foo&quot; &gt; /foo +EOF + +$&gt; cat &lt;&lt;EOF &gt; package/definition.yaml +name: &quot;foo&quot; +version: &quot;0.1&quot; +category: &quot;bar&quot; # optional! +EOF + +$&gt; luet build --all --destination $PWD/out/ --tree $PWD/package + +📦 Selecting foo 0.1 +📦 Compiling foo version 0.1 .... ☕ +🐋 Downloading image luet/cache-foo-bar-0.1-builder +🐋 Downloading image luet/cache-foo-bar-0.1 +📦 foo Generating 🐋 definition for builder image from busybox +🐋 Building image luet/cache-foo-bar-0.1-builder +🐋 Building image luet/cache-foo-bar-0.1-builder done + Sending build context to Docker daemon 4.096kB + ... + +$&gt; luet create-repo --name &quot;test&quot; --output $PWD/out --packages $PWD/out --tree $PWD/package + For repository test creating revision 1 and last update 1580641614... + +$&gt; ls out +foo-bar-0.1-builder.image.tar foo-bar-0.1.image.tar foo-bar-0.1.metadata.yaml foo-bar-0.1.package.tar repository.yaml tree.tar + +</code></pre><h3 id="repositories-type">Repositories type</h3> +<p>There are 3 types of repositories supported by luet: <code>disk</code>, <code>http</code>, <code>docker</code>.</p> +<h4 id="disk"><code>disk</code></h4> +<p>It is a repository which is merely a local folder in your system. When creating a repository and specifying <code>--output</code>, <code>luet</code> expects a local path to the system where to store the generated metadata.</p> +<h4 id="http"><code>http</code></h4> +<p>It is a repository type which is hosted behind a webserver. When creating a repository and specifying <code>--output</code>, <code>luet</code> expects a local path to the system where to store the generated metadata, similarly to the <code>disk</code> repository type. Luet is not handling any file upload. The <code>http</code> repository type gains meaning when being used from the client, where the repository source must be specified</p> +<h4 id="docker"><code>docker</code></h4> +<p>When specifying the <code>docker</code> repository type, <code>luet</code> will generate final images from the build results and upload them to the docker reference specified with <code>--output</code>. The images contains the artifact output from the build result, and they are tagged accordingly to their package name. A single image reference needs to be passed, all the packages will be pushed in a single image but with different tags.</p> +<p>The login to the container registry is not handled, the daemon needs to have already proper permissions to push the image to the destination.</p> +<h2 id="notes">Notes</h2> +<ul> +<li>The tree of definition being used to build the repository, and the package directories must <strong>not</strong> be symlinks.</li> +<li>To build a repository is not required to hold the packages artifacts, only the respective <code>metadata.yaml</code> file is required.</li> +</ul> + + + + + + Docs: Specfile + https://luet-lab.github.io/docs/docs/concepts/packages/specfile/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/packages/specfile/ + + + + <h1 id="specfiles">Specfiles</h1> +<p>Luet <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/">packages</a> are defined by specfiles. Specfiles define the runtime and builtime requirements of a package. There is an hard distinction between runtime and buildtime. A spec is composed at least by the runtime (<code>definition.yaml</code> or a <code>collection.yaml</code>) and the buildtime specification (<code>build.yaml</code>).</p> +<p>Luet identifies the package definition by looking at directories that contains a <code>build.yaml</code> and a <code>definition.yaml</code> (or <code>collection.yaml</code>) files. A Luet tree is merely a composition of directories that follows this convention. There is no constriction on either folder naming or hierarchy.</p> +<p><em>Example of a <a href="https://github.com/Luet-lab/luet-embedded/tree/master/distro">tree folder hierarchy</a></em></p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">tree distro +distro +├── funtoo +│   ├── 1.4 +│   │   ├── build.sh +│   │   ├── build.yaml +│   │   ├── definition.yaml +│   │   └── finalize.yaml +│   ├── docker +│   │   ├── build.yaml +│   │   ├── definition.yaml +│   │   └── finalize.yaml +│   └── meta +│   └── rpi +│   └── 0.1 +│   ├── build.yaml +│   └── definition.yaml +├── packages +│   ├── container-diff +│   │   └── 0.15.0 +│   │   ├── build.yaml +│   │   └── definition.yaml +│   └── luet +│   ├── build.yaml +│   └── definition.yaml +├── raspbian +│   ├── buster +│   │   ├── build.sh +│   │   ├── build.yaml +│   │   ├── definition.yaml +│   │   └── finalize.yaml +│   ├── buster-boot +│   │   ├── build.sh +│   │   ├── build.yaml +│   │   ├── definition.yaml +│   │   └── finalize.yaml +</code></pre></div><h2 id="build-specs">Build specs</h2> +<p>Build specs are defined in <code>build.yaml</code> files. They denote the build-time <code>dependencies</code> and <code>conflicts</code>, together with a definition of the content of the package.</p> +<p><em>Example of a <code>build.yaml</code> file</em>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo &#34;Luet is awesome&#34; &gt; /awesome</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">prelude</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo &#34;nooops!&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;echo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">provides</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">env</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">FOO=bar</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">includes</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/awesome</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">unpack</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="building-strategies">Building strategies</h3> +<p>Luet can create packages with different strategies:</p> +<ul> +<li>by delta. Luet will analyze the containers differencies to find out which files got <strong>added</strong>. +You can use the <code>prelude</code> section to exclude certains file during analysis.</li> +<li>by taking a whole container content</li> +<li>by considering a single directory in the build container.</li> +</ul> +<h4 id="package-by-delta">Package by delta</h4> +<p>By default Luet will analyze the container content and extract any file that gets <strong>added</strong> to it. The difference is calculated by using the container which is depending on, or either by the container which is created by running the steps in the <code>prelude</code> section of the package build spec:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">prelude</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#8f5902;font-style:italic"># do something...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#8f5902;font-style:italic"># real work that should be calculated delta over</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>By omitting the <code>prelude</code> keyword, the delta will be calculated from the parent container where the build will start from.</p> +<h4 id="package-by-container-content">Package by container content</h4> +<p>Luet can also generate a package content from a container. This is really useful when creating packages that are entire versioned <code>rootfs</code>. To enable this behavior, simply add <code>unpack: true</code> to the <code>build.yaml</code>. This enables the Luet unpacking features, which will extract all the files contained in the container which is built from the <code>prelude</code> and <code>steps</code> fields.</p> +<p>To include/exclude single files from it, use the <code>includes</code> and <code>excludes</code> directives.</p> +<h4 id="package-by-a-folder-in-the-final-container">Package by a folder in the final container</h4> +<p>Similarly, you can tell Luet to create a package from a folder in the build container. To enable this behavior, simply add <code>package_dir: &quot;/path/to/final/dir&quot;</code>. +The directory must represent exactly how the files will be ultimately installed from clients, and they will show up in the same layout in the final archive.</p> +<p>So for example, to create a package which ships <code>/usr/bin/mybin</code>, we could write:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">package_dir</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/output&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">mkdir -p /output/usr/bin/</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo &#34;fancy stuff&#34; &gt; /output/usr/bin/mybin &amp;&amp; chmod +x /output/usr/bin/mybin</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="build-time-dependencies">Build time dependencies</h3> +<p>A package build spec defines how a package is built. In order to do this, Luet needs to know where to start. Hence a package must declare at least either one of the following:</p> +<ul> +<li>an <code>image</code> keyword which tells which Docker image to use as base, or</li> +<li>a list of <code>requires</code>, which are references to other packages available in the tree.</li> +</ul> +<p>They can&rsquo;t be both present in the same specfile.</p> +<p>To note, it&rsquo;s not possible to mix package build definitions from different <code>image</code> sources. They must form a unique sub-graph in the build dependency tree.</p> +<p>On the other hand it&rsquo;s possible to have multiple packages depending on a combination of different <code>requires</code>, given they are coming from the same <code>image</code> parent.</p> +<h3 id="excludingincluding-files-explictly">Excluding/including files explictly</h3> +<p>Luet can also <em>exclude</em> and <em>include</em> single files or folders from a package by using the <code>excludes</code> and <code>includes</code> keyword respecitvely.</p> +<p>Both of them are parsed as a list of Golang regex expressions, and they can be combined together to fine-grainly decide which files should be inside the final artifact. You can refer to the files as they were in the resulting package. So if a package produces a <code>/foo</code> file, and you want to exclude it, you can add it to <code>excludes</code> as <code>/foo</code>.</p> +<h3 id="package-source-image">Package source image</h3> +<p>Luet needs an image to kick-off the build process for each package. This image is being used to run the commands in the <code>steps</code> and <code>prelude</code>, and then the image is processed by the <strong>building strategies</strong> explained above.</p> +<p>The image can be resolved either by:</p> +<ol> +<li>providing a specific image name with <code>image</code></li> +<li>providing a set of package requirements with <code>requires</code> which will be constructed a new image from. The resulting image is an image linked between each other with the <code>FROM</code> field in the Dockerfile following the SAT solver ordering.</li> +<li>providing a set of packages to squash their result from <code>requires</code> and by specifying <code>requires_final_images: true</code>.</li> +</ol> + + +<div class="alert alert-info" role="alert"> +<h4 class="alert-heading">Note</h4> + + The above keywords cannot be present in the same spec <strong>at the same time</strong>, or they cannot be combined. But you are free to create further intermediate specs to achieve the desired image. + +</div> + +<h4 id="difference-between-requires-and-requires-with-requires_final_images-true">Difference between <code>requires</code> and <code>requires</code> with <code>requires_final_images: true</code></h4> +<p><code>requires</code> generates a graph from all the <code>images</code> of the specfile referenced inside the list. This means it builds a chain of images that are used to build the packages, e.g.: <code>packageA(image: busybox) -&gt; packageB (requires: A) -&gt; packageC (requires: C)</code>. The container which is running your build then <strong>inherits</strong> it&rsquo;s parents from a chain of order resolution, provided by the SAT solver.</p> +<p>When specifying <code>requires_final_images: true</code> luet builds an artifact for each of the packages listed from their compilation specs and it will later <em>squash</em> them together in a new container image which is then used in the build process to create an artifact.</p> +<p>The key difference is about <em>where</em> your build is going to run from. By specifying <code>requires_final_images</code> it will be constructed a new image with the content of each package - while if setting it to false, it will order the images appropriately and link them together with the Dockerfile <code>FROM</code> field. That allows to reuse the same images used to build the packages in the require section - or - create a new one from the result of each package compilation.</p> +<h2 id="keywords">Keywords</h2> +<p>Here is a list of the full keyword refereces for the <code>build.yaml</code> file.</p> +<h3 id="conflicts"><code>conflicts</code></h3> +<p>(optional) List of packages which it conflicts with in <em>build time</em>. In the same form of <code>requires</code> it is a list of packages that the current one is conflicting with.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>See <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages">Package concepts</a> for more information on how to represent a package in a Luet tree.</p> +<h3 id="copy"><code>copy</code></h3> +<p><em>since luet&gt;=0.15.0</em></p> +<p>(optional) A list of packages/images where to copy files from. It is the <a href="https://docs.docker.com/develop/develop-images/multistage-build/">Docker multi-stage build</a> equivalent but enhanced with tree hashing resolution.</p> +<p>To copy a specific file from a package <em>build</em> container:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">prelude</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">copy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">package</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">source</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">destination</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>Any package that is listed in the section will be compiled beforeahead the package, and the file is available both in <code>prelude</code> and <code>steps</code>.</p> +<p>Internally, it&rsquo;s rendered as <code>COPY --from=package/image:sha /foo /bar</code></p> +<p>To copy a specific file from an external image:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">prelude</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">copy</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;buxybox:latest&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">source</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">destination</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;/bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="env"><code>env</code></h3> +<p>(optional) A list of environment variables ( in <code>NAME=value</code> format ) that are expanded in <code>step</code> and in <code>prelude</code>. ( e.g. <code>${NAME}</code> ).</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">env</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">PATH=$PATH:/usr/local/go/bin</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">GOPATH=/luetbuild/go</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">GO111MODULE=on</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">CGO_ENABLED=0</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">LDFLAGS=&#34;-s -w&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="excludes"><code>excludes</code></h3> +<p>(optional) List of golang regexes. They are in full path form (e.g. <code>^/usr/bin/foo</code> ) and indicates that the files listed shouldn&rsquo;t be part of the final artifact</p> +<p>Wildcards and golang regular expressions are supported. If specified, files which are not matching any of the regular expressions in the list will be excluded in the final package.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">excludes</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">^/etc/shadow</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">^/etc/os-release</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">^/etc/gshadow</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>By combining <code>excludes</code> with <code>includes</code>, it&rsquo;s possible to include certain files while excluding explicitly some others (<code>excludes</code> takes precedence over <code>includes</code>).</p> +<h3 id="image"><code>image</code></h3> +<p>(optional/required) Docker image to be used to build the package.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;busybox&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>It might be omitted in place of <code>requires</code>, and indicates the image used to build the package. The image will be pulled and used to build the package.</p> +<h3 id="includes"><code>includes</code></h3> +<p>(optional) List of regular expressions to match files in the resulting package. The path is absolute as it would refer directly to the artifact content.</p> +<p>Wildcards and golang regular expressions are supported. If specified, files which are not matching any of the regular expressions in the list will be excluded in the final package.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">includes</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/etc$</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/etc/lvm$</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/etc/lvm/.*</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/usr$</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/usr/bin$</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/usr/bin/cc.*</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/usr/bin/c\+\+.*</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/usr/bin/cpp.*</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/usr/bin/g\+\+.*</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><strong>Note</strong>: Directories are treated as standard entries, so to include a single file, you need also to explictly include also it&rsquo;s directory. Consider this example to include <code>/etc/lvm/lvm.conf</code>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">includes</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/etc$</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/etc/lvm$</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">/etc/lvm/lvm.conf</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="join"><code>join</code></h3> +<p><em>since luet&gt;=0.16.0</em> +<em>to be deprecated in luet&gt;=0.18.0 in favor of <code>requires_final_images</code></em></p> +<p>(optional/required) List of packages which are used to generate a parent image from.</p> +<p>It might be omitted in place of <code>image</code> or <code>requires</code>, and will generate an image which will be used as source of the package from the final packages in the above list. The new image is used to run eventually the package building process and a new artifact can be generated out of it.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">join</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>See <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages">Package concepts</a> for more information on how to represent a package in a Luet tree.</p> +<h4 id="examples">Examples</h4> +<ul> +<li><a href="https://github.com/mocaccinoOS/mocaccino-stage3/blob/278e3637cf65761bf01a22c891135e237e4717ad/packages/system/stage3/build.yaml">https://github.com/mocaccinoOS/mocaccino-stage3/blob/278e3637cf65761bf01a22c891135e237e4717ad/packages/system/stage3/build.yaml</a></li> +</ul> +<h3 id="package_dir"><code>package_dir</code></h3> +<p>(optional) A path relative to the build container where to create the package from.</p> +<p>Similarly to <code>unpack</code>, changes the building strategy.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">mkdir -p /foo/bar/etc/myapp</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">touch /foo/bar/etc/myapp/config</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">package_dir</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">/foo/bar</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="prelude"><code>prelude</code></h3> +<p>(optional) A list of commands to perform in the build container before building.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">prelude</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000;font-weight:bold">|</span><span style="color:#8f5902;font-style:italic"> +</span><span style="color:#8f5902;font-style:italic"> PACKAGE_VERSION=${PACKAGE_VERSION%\+*} &amp;&amp; \ +</span><span style="color:#8f5902;font-style:italic"> git clone https://github.com/mudler/yip &amp;&amp; cd yip &amp;&amp; git checkout &#34;${PACKAGE_VERSION}&#34; -b build</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="requires"><code>requires</code></h3> +<p>(optional/required) List of packages which it depends on.</p> +<p>A list of packages that the current package depends on in <em>build time</em>. It might be omitted in place of <code>image</code>, and determines the resolution tree of the package itself. A new image is composed from the packages listed in this section in order to build the package</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>See <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages">Package concepts</a> for more information on how to represent a package in a Luet tree.</p> +<h3 id="requires_final_images"><code>requires_final_images</code></h3> +<p><em>since luet&gt;=0.17.0</em></p> +<p>(optional) A boolean flag which instruct luet to use the final images in the <code>requires</code> field.</p> +<p>By setting <code>requires_final_images: true</code> in the compilation spec, packages in the <code>requires</code> section will be first compiled, and afterwards the final packages are squashed together in a new image that will be used during build.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">requires_final_images</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p><code>requires_final_images</code> replaces the use of <code>join</code>, which will be deprecated in luet <code>&gt;=0.18.0</code>.</p> +<h3 id="step"><code>step</code></h3> +<p>(optional) List of commands to perform in the build container.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000;font-weight:bold">|</span><span style="color:#8f5902;font-style:italic"> +</span><span style="color:#8f5902;font-style:italic"> </span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">cd yip &amp;&amp; make build-small &amp;&amp; mv yip /usr/bin/yip</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="unpack"><code>unpack</code></h3> +<p>(optional) Boolean flag. It indicates to use the unpacking strategy while building a package</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">unpack</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>It indicates that the package content <strong>is</strong> the whole container content.</p> +<h2 id="rutime-specs">Rutime specs</h2> +<p>Runtime specification are denoted in a <code>definition.yaml</code> or a <code>collection.yaml</code> sibiling file. It identifies the package and the runtime contraints attached to it.</p> +<p><em>definition.yaml</em>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;awesome&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;echo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">provides</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&lt;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>A <code>collection.yaml</code> can be used in place of a <code>definition.yaml</code> to identify a <strong>set</strong> of packages that instead shares a common <code>build.yaml</code>:</p> +<p><em>collection.yaml</em>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">packages</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;awesome&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;echo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">provides</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&lt;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;awesome&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;0.2&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;echo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&gt;=1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">provides</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;&lt;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>All the fields (also the ones which are not part of the spec) in the <code>definition.yaml</code> file are available as templating values when rendering the <code>build.yaml</code> file. When running <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/specfile/#finalizers">finalizers</a> instead only the fields belonging to the specs are available.</p> +<h3 id="keywords-1">Keywords</h3> +<p>Here is a list of the full keyword refereces</p> +<h3 id="annotations"><code>annotations</code></h3> +<p>(optional) A map of freeform package annotations:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">annotations</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">foo</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">baz</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h4 id="category"><code>category</code></h4> +<p>(optional) A string containing the category of the package</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;system&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="conflicts-1"><code>conflicts</code></h3> +<p>(optional) List of packages which it conflicts with in <em>runtime</em>. In the same form of <code>requires</code> it is a list of packages that the current one is conflicting with.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>See <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages">Package concepts</a> for more information on how to represent a package in a Luet tree.</p> +<h3 id="description"><code>description</code></h3> +<p>(optional) A string indicating the package description</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">description</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo is capable of...&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="hidden"><code>hidden</code></h3> +<p>(optional) A boolean indicating whether the package has to be shown or not in the search results (<code>luet search...</code>)</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">hidden</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">true</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="labels"><code>labels</code></h3> +<p>(optional) A map of freeform package labels:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">labels</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">foo</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">baz</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>Labels can be used in <code>luet search</code> to find packages by labels, e.g.:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$&gt; luet search --by-label foo +</code></pre></div><h3 id="license"><code>license</code></h3> +<p>(optional) A string indicating the package license type.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">license</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;GPL-3&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h4 id="name"><code>name</code></h4> +<p>(required) A string containing the name of the package</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="provides"><code>provides</code></h3> +<p>(optional) List of packages which the current package is providing.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">conflicts</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>See <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages">Package concepts</a> for more information on how to represent a package in a Luet tree.</p> +<h3 id="requires-1"><code>requires</code></h3> +<p>(optional) List of packages which it depends on in runtime.</p> +<p>A list of packages that the current package depends on in <em>runtime</em>. The determines the resolution tree of the package itself.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">requires</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>See <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages">Package concepts</a> for more information on how to represent a package in a Luet tree.</p> +<h3 id="uri"><code>uri</code></h3> +<p>(optional) A list of URI relative to the package ( e.g. the official project pages, wikis, README, etc )</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">uri</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#4e9a06">&#34;http://www.mocaccino.org&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h4 id="version"><code>version</code></h4> +<p>(required) A string containing the version of the package</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h2 id="refering-to-packages-from-the-cli">Refering to packages from the CLI</h2> +<p>All the <code>luet</code> commands which takes a package as argument, respect the following syntax notation:</p> +<ul> +<li><code>cat/name</code>: will default to selecting any available package</li> +<li><code>=cat/name</code>: will default to gentoo parsing with regexp so also <code>=cat/name-1.1</code> works</li> +<li><code>cat/name@version</code>: will select the specific version wanted ( e.g. <code>cat/name@1.1</code> ) but can also include ranges as well <code>cat/name@&gt;=1.1</code></li> +<li><code>name</code>: just name, category is omitted and considered empty</li> +</ul> +<h2 id="finalizers">Finalizers</h2> +<p>Finalizers are denoted in a <code>finalize.yaml</code> file, which is a sibiling of <code>definition.yaml</code> and <code>build.yaml</code> file. It contains a list of commands that finalize the package when it is installed in the machine.</p> +<p><em>finalize.yaml</em>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">install</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">rc-update add docker default</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><h3 id="keywords-2">Keywords</h3> +<ul> +<li><code>install</code>: List of commands to run in the host machine. Failures are eventually ignored, but will be reported and luet will exit non-zero in such case.</li> +</ul> + + + + + + Docs: CLI usage + https://luet-lab.github.io/docs/docs/concepts/overview/usage/ + Sat, 14 Dec 2019 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/overview/usage/ + + + + <h2 id="installing-a-package">Installing a package</h2> +<p>To install a package with <code>luet</code>, simply run:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet install &lt;package_name&gt; + +</code></pre></div><p>To relax dependency constraints and avoid auto-upgrades, add the <code>--relax</code> flag:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet install --relax &lt;package name&gt; +</code></pre></div><p>To install only the package without considering the deps, add the <code>--nodeps</code> flag:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet install --nodeps &lt;package name&gt; +</code></pre></div><p>To install only package dependencies, add the <code>--onlydeps</code> flag:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet install --onlydeps &lt;package name&gt; +</code></pre></div><p>To only download packages, without installing them use the <code>--download-only</code> flag:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet install --download-only &lt;package name&gt; +</code></pre></div><h2 id="uninstalling-a-package">Uninstalling a package</h2> +<p>To uninstall a package with <code>luet</code>, simply run:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet uninstall &lt;package_name&gt; + +</code></pre></div><h2 id="upgrading-the-system">Upgrading the system</h2> +<p>To upgrade your system, simply run:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet upgrade +</code></pre></div><h2 id="refreshing-repositories">Refreshing repositories</h2> +<p>Luet automatically syncs repositories definition on the machine when necessary, but it avoids to sync up in a 24h range. In order to refresh the repositories manually, run:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet repo update +</code></pre></div><h2 id="searching-a-package">Searching a package</h2> +<p>To search a package:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet search &lt;regex&gt; + +</code></pre></div><p>To search a package and display results in a table:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet search --table &lt;regex&gt; + +</code></pre></div><p>To look into the installed packages:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet search --installed &lt;regex&gt; + +</code></pre></div><p>Note: the regex argument is optional</p> +<h2 id="search-file-belonging-to-packages">Search file belonging to packages</h2> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ luet search --file &lt;file_pattern&gt; +</code></pre></div><h3 id="search-output">Search output</h3> +<p>Search can return results in the terminal in different ways: as terminal output, as json or as yaml.</p> +<h4 id="json">JSON</h4> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet search --json &lt;regex&gt; + +</code></pre></div><h4 id="yaml">YAML</h4> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet search --yaml &lt;regex&gt; + +</code></pre></div><h4 id="tabular">Tabular</h4> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +$ luet search --table &lt;regex&gt; + +</code></pre></div><h2 id="quiet-luet-output">Quiet luet output</h2> +<p>Luet output is verbose by default and colourful, however will try to adapt to the terminal, based on which environment is executed (as a service, in the terminal, etc.)</p> +<p>You can quiet <code>luet</code> output with the <code>--quiet</code> flag or <code>-q</code> to have a more compact output in all the commands.</p> + + + + + + Docs: Build a package + https://luet-lab.github.io/docs/docs/tutorials/build_package/ + Wed, 04 Jan 2017 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/tutorials/build_package/ + + + + + +<div class="alert alert-warning" role="alert"> +<h4 class="alert-heading">Warning</h4> + + This article contains references to Luet repositories that were deprecated, and needs to be updated. +Please refer to the <a href="../../tutorials/hello_world/">&ldquo;Hello World&rdquo;</a> tutorial instead. + +</div> + +<p><img src="https://github.com/BarkyTheDog/catclock/raw/master/catclock.gif" alt="catclock"></p> +<h1 id="catclock-example">Catclock example</h1> +<p>In this example, we will build the awesome <a href="https://github.com/BarkyTheDog/catclock">CatClock</a> on containers we will run it locally in a Luet box.</p> +<p>We will do this experiment to prove two things:</p> +<ol> +<li>how we can build a package with Luet and</li> +<li>two packages from different distributions can (sometime) work together.</li> +</ol> +<h2 id="prerequisites">Prerequisites</h2> +<p>To build packages with Luet, you must have installed Docker and container-diff, follow our <a href="../../getting-started">setup guide</a>.</p> +<h2 id="1-create-the-package">1) Create the package</h2> +<p>To prove our point, we will build our package from an OpenSUSE image, and later on we will consume +entropy repositories for runtime dependencies. To note, this is not the main focus of Luet, and this is a restricted example on its features on build-time resolution. For more syntax examples, see also <a href="../../concepts/specfile/#build-specs">Build specs</a> and <a href="../../concepts/packages/#package-types">Package types</a>.</p> +<p>Run this commands in any directory you choose to be your workspace:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +<span style="color:#8f5902;font-style:italic"># Let&#39;s create a directory to store our package spec:</span> +mkdir -p tree/misc/catclock/ +</code></pre></div><h3 id="11-build-spec">1.1) Build spec</h3> +<p>Now, let&rsquo;s generate our <strong>build</strong> spec:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># Create a build file. We use here opensuse/leap to build the package, as an example</span> +cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; tree/misc/catclock/build.yaml +</span><span style="color:#4e9a06">image: opensuse/leap +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06"># Preparation phase +</span><span style="color:#4e9a06">prelude: +</span><span style="color:#4e9a06">- zypper in -y git make libXt-devel xmh gcc motif-devel libXext-devel libpulse-devel libaubio-devel +</span><span style="color:#4e9a06">- git clone https://github.com/BarkyTheDog/catclock +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06"># Here we define the steps that Luet will follow +</span><span style="color:#4e9a06">steps: +</span><span style="color:#4e9a06">- cd catclock &amp;&amp; make DEFINES=&#34;-Wno-incompatible-pointer-types&#34; +</span><span style="color:#4e9a06">- mv catclock/xclock /usr/bin/xclock +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06"># (optional) File list that will be included in the final package +</span><span style="color:#4e9a06"># Luet will filter out files that won&#39;t match any entry in the list (regex syntax IS supported) +</span><span style="color:#4e9a06">includes: +</span><span style="color:#4e9a06">- /usr/bin/xclock +</span><span style="color:#4e9a06">EOF</span> + +</code></pre></div><p><code>build.yaml</code> is what an ebuild is for Gentoo and for e.g. what PKGBUILD is for Arch.</p> +<ul> +<li><em>image: opensuse/leap</em> tells luet to use opensuse/leap as a build image. We collect the build time dependencies with <code>zypper</code> (the openSUSE package manager), and the <a href="https://github.com/BarkyTheDog/catclock">CatClock</a> with <code>git</code>. When we declare an <code>image</code> keyword in a spec, it becomes a <em>seed</em> package ( <a href="../../concepts/packages/#package-types">Package types</a> ) as doesn&rsquo;t depend on any package in build time, we will cover more use cases in other examples.</li> +<li><em>prelude</em> is a list of commands that will happen during the build phase. +They might generate binaries, or download sources, but those are not took into consideration when generating the final package.</li> +<li><em>steps</em> is a list of commands that will happen during the build phase. +Luet will execute those commands and all the binaries generated from them become part of the final package</li> +<li><em>includes</em> is a (optional) list of regex that tells to Luet what files to filter out from the final artifact.</li> +</ul> +<h3 id="12-runtime-spec">1.2) Runtime spec</h3> +<p>Now we generate the runtime spec, it&rsquo;s the part about the binary end which will be installed in the system. It also holds the metadata relative to the package definition (<code>name</code>, <code>category</code>, <code>version</code>).</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># Create a runtime definition.</span> +<span style="color:#8f5902;font-style:italic"># We will leverage packages already present on Sabayon Entropy repositories</span> +<span style="color:#8f5902;font-style:italic"># the end-system needs to have the Luet Sabayon Entropy repositories enabled.</span> +cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; tree/misc/catclock/definition.yaml +</span><span style="color:#4e9a06">category: &#34;misc&#34; +</span><span style="color:#4e9a06">name: &#34;catclock&#34; +</span><span style="color:#4e9a06">version: &#34;0.20200318&#34; +</span><span style="color:#4e9a06">requires: +</span><span style="color:#4e9a06">- category: meta +</span><span style="color:#4e9a06"> name: users +</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34; +</span><span style="color:#4e9a06">- category: x11-libs +</span><span style="color:#4e9a06"> name: motif +</span><span style="color:#4e9a06"> version: &#34;&gt;=0.1&#34; +</span><span style="color:#4e9a06">- category: media-libs +</span><span style="color:#4e9a06"> name: libjpeg-turbo +</span><span style="color:#4e9a06"> version: &#34;&gt;=0.1&#34; +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><ul> +<li><em>category</em>, <em>name</em>, and <em>version</em>: identifies the package in a Luet tree. This is the unique identifier for a package.</li> +<li><em>requires</em> it&rsquo;s a list of packages which our <strong>catclock</strong> depends on during runtime (when we will execute catclock inside a small-container!). To find out what&rsquo;s required by your binaries it can be a try-learn-fail effort. If the package you wish to build is specifying the deps it requires, and those are available in a Luet repository, you are all set, just point them there. Otherwise you have to figure out after you build the binary the first time (for example, with <code>ldd</code>) to which libraries it depends on. +In this example we consume the dependencies from the <a href="https://github.com/Luet-lab/luet-entropy-repo">Luet Entropy Repo</a>, that we will enable on the following steps.</li> +</ul> +<h2 id="2-build-it">2) Build it!</h2> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">sudo /usr/bin/luet build <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--tree<span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">$PWD</span>/tree misc/catclock <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--destination <span style="color:#000">$PWD</span>/build <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--compression gzip + +sudo chown -R <span style="color:#000">$USER</span> <span style="color:#000">$PWD</span>/build <span style="color:#8f5902;font-style:italic"># So later on, we can access to the repository with our user</span> +</code></pre></div><p>We are building the specs in this step.</p> +<ul> +<li><em>tree</em>: is the path where our specs are, in our case it&rsquo;s <code>tree</code>.</li> +<li><em>destination</em>: is the path where our packages will be stored, in our case this is <code>build</code>.</li> +<li><em>compression</em>: is the compression algorithm used to compress the final artifacts</li> +</ul> +<p>Note, we need <em>sudo</em> to keep the permissions properly mapped in the artifact which is produced +this is not always the case. Depends on the package content.</p> +<h2 id="3-create-a-local-repository">3) Create a local repository</h2> +<p>We will generate now our repository metadata:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">/usr/bin/luet create-repo --tree <span style="color:#4e9a06">&#34;tree&#34;</span> <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--output <span style="color:#000">$PWD</span>/build <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--packages <span style="color:#000">$PWD</span>/build <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--name <span style="color:#4e9a06">&#34;test repo&#34;</span> <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--descr <span style="color:#4e9a06">&#34;Test Repo&#34;</span> <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--tree-compression gzip <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--meta-compression gzip +</code></pre></div><p>Creating a repository in Luet is about adding metadata and make our spec tree available to other systems running Luet to intall the package.</p> +<ul> +<li><strong>output</strong>: a path which is where Luet will store the repository metadata.</li> +<li><strong>packages</strong>: a path containing the packages that were built during the build step</li> +<li><strong>name</strong>: Repository name</li> +<li><strong>descr</strong>: Repository description</li> +<li><strong>tree-compression</strong>: optional, algorithm to use when compression the tree metadata</li> +<li><strong>meta-compression</strong>: optional, algorithm to use when compression the repository metadata</li> +</ul> +<h2 id="4-lets-test-it">4) Let&rsquo;s test it!</h2> +<p>Now we are all set. We have the packages compiled, and we are ready to consume them. We don&rsquo;t want to break our host system, and we want to test this from our user.</p> +<p>Let&rsquo;s create a directory, we will try to setup a full running system, and install everything there.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># Let&#39;s create a directory for our &#34;fake&#34; rootfilesystem</span> +<span style="color:#8f5902;font-style:italic"># it will be populated with a minimal set of packages needed to run </span> +<span style="color:#8f5902;font-style:italic"># our amazing catclock</span> +mkdir -p <span style="color:#000">$PWD</span>/rootfs +</code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># Let&#39;s also create a directory to store our config files</span> +mkdir -p <span style="color:#000">$PWD</span>/conf +</code></pre></div><p>We will generate now a Luet config. The Luet config is used to read where install things from, and in which directory. +It also lists the repositories that are used by the client to retrieve packages remotely.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># We create here a config file which references the rootfs.</span> +<span style="color:#8f5902;font-style:italic"># In this way, luet instead installing packages to your host system, will populate the rootfs</span> +<span style="color:#8f5902;font-style:italic"># (note, all the steps are run by a user here, no root required!)</span> +cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; conf/luet-dso-local.yaml +</span><span style="color:#4e9a06">system: +</span><span style="color:#4e9a06"> rootfs: $PWD/rootfs # our &#34;fake&#34; rootfs that we created before +</span><span style="color:#4e9a06"> database_path: &#34;/&#34; # this is where our Luet DB will live +</span><span style="color:#4e9a06"> database_engine: &#34;boltdb&#34; # this is the Luet DB engine +</span><span style="color:#4e9a06">repositories: +</span><span style="color:#4e9a06"> - name: &#34;main&#34; +</span><span style="color:#4e9a06"> type: &#34;disk&#34; +</span><span style="color:#4e9a06"> priority: 3 +</span><span style="color:#4e9a06"> enable: true +</span><span style="color:#4e9a06"> urls: +</span><span style="color:#4e9a06"> - &#34;$PWD/build&#34; # This is the repository we have created before! +</span><span style="color:#4e9a06"> - name: &#34;sabayonlinux.org&#34; +</span><span style="color:#4e9a06"> description: &#34;Sabayon Linux Repository&#34; +</span><span style="color:#4e9a06"> type: &#34;http&#34; +</span><span style="color:#4e9a06"> enable: true +</span><span style="color:#4e9a06"> cached: true +</span><span style="color:#4e9a06"> priority: 2 +</span><span style="color:#4e9a06"> urls: +</span><span style="color:#4e9a06"> - &#34;https://dispatcher.sabayon.org/sbi/namespace/luet-entropy-repo&#34; +</span><span style="color:#4e9a06"> - name: &#34;luet-repo&#34; +</span><span style="color:#4e9a06"> description: &#34;Luet Official Repository&#34; +</span><span style="color:#4e9a06"> type: &#34;http&#34; +</span><span style="color:#4e9a06"> enable: true +</span><span style="color:#4e9a06"> cached: true +</span><span style="color:#4e9a06"> priority: 1 +</span><span style="color:#4e9a06"> urls: +</span><span style="color:#4e9a06"> - &#34;https://raw.githubusercontent.com/Luet-lab/luet-repo/gh-pages&#34; +</span><span style="color:#4e9a06">EOF</span> +<span style="color:#8f5902;font-style:italic"># we have specified an additional repository, one that is luet-entropy-repo (which contains</span> +<span style="color:#8f5902;font-style:italic"># the runtime dependencies we specified in our package)</span> +</code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># Let&#39;s populate our rootfs with some minimal things: base-gcc, and bash</span> +<span style="color:#8f5902;font-style:italic"># meta/users is a meta package providing minimal base to run things with a full</span> +<span style="color:#8f5902;font-style:italic"># user-level support.</span> +<span style="color:#204a87">export</span> <span style="color:#000">LUET_NOLOCK</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#204a87">true</span> +luet install <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--config <span style="color:#000">$PWD</span>/conf/luet-dso-local.yaml <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>meta/users +</code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># catclock is a X11 app! we want to be able to play with it locally from our host :)</span> +<span style="color:#8f5902;font-style:italic"># Let&#39;s copy the .Xauthority file to allow the X app to communicate with our X server</span> +<span style="color:#8f5902;font-style:italic"># Note: This can be achieved in other ways (set up a tcp X server, and so on)</span> +cp -rfv <span style="color:#000">$HOME</span>/.Xauthority <span style="color:#000">$PWD</span>/rootfs/ +</code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">luet install <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--config <span style="color:#000">$PWD</span>/conf/luet-dso-local.yaml <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>misc/catclock +</code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># Let&#39;s run our beautiful catclock :)</span> +luet box <span style="color:#204a87">exec</span> --rootfs <span style="color:#000">$PWD</span>/rootfs <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--stdin --stdout --stderr --env <span style="color:#000">DISPLAY</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">$DISPLAY</span> <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--env <span style="color:#000">XAUTHORITY</span><span style="color:#ce5c00;font-weight:bold">=</span>/.Xauthority --mount /tmp --entrypoint /usr/bin/xclock +</code></pre></div><p>Spawn a bash shell inside our box (with permission to access to our running X):</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">luet box <span style="color:#204a87">exec</span> --rootfs <span style="color:#000">$PWD</span>/rootfs <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--stdin --stdout --stderr --env <span style="color:#000">DISPLAY</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">$DISPLAY</span> <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--env <span style="color:#000">XAUTHORITY</span><span style="color:#ce5c00;font-weight:bold">=</span>/.Xauthority --mount /tmp --entrypoint /bin/bash +</code></pre></div> + + + + + Docs: Templated packages + https://luet-lab.github.io/docs/docs/concepts/packages/templates/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/packages/templates/ + + + + <p>Luet supports the <a href="http://masterminds.github.io/sprig/"><code>sprig</code> rendering engine template, like helm</a>. It&rsquo;s being used to interpolate <code>build.yaml</code> and <code>finalize.yaml</code> files before their execution. The following document assumes you are familiar with the <code>helm</code> templating.</p> +<p>The <code>build.yaml</code> and <code>finalize.yaml</code> files are rendered during build time, and it&rsquo;s possible to use the <code>helm</code> templating syntax inside such files. The <code>definition.yaml</code> file will be used to interpolate templating values available in <code>build.yaml</code></p> +<p>Given the following <code>definition.yaml</code>:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.1&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">additional_field</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;baz&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>A <code>build.yaml</code> can look like the following, and interpolates it&rsquo;s values during build time:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo {{.Values.name}} &gt; /package_name</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo {{.Values.additional_field}} &gt; /extra</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>Which would be for example automatically rendered by luet like the following:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">...</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo test &gt; /package_name</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo baz &gt; /extra</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div><p>This mechanism can be used in collections as well, and each stanza in <code>packages</code> is used to interpolate each single package.</p> +<h2 id="interpolating-globally">Interpolating globally</h2> +<p>It&rsquo;s possible to interpolate during build phase all the package specs targeted for build with the <code>--values</code> flag, which takes a yaml file of an arbitrary format, if variables are clashing, the yaml supplied in <code>--values</code> takes precedence and overwrite the values of each single <code>definition.yaml</code> file.</p> +<h2 id="shared-templates">Shared templates</h2> +<p>Since luet <code>0.17.5</code> it is possible to share templates across different packages. All templates blocks found inside the <code>templates</code> folder inside the root <code>luet tree</code> of a repository gets templated and shared across all the packages while rendering each compilation spec of the given tree.</p> +<p>Consider the following:</p> +<pre tabindex="0"><code>shared_templates +├── templates +│   └── writefile.yaml +└── test + ├── build.yaml + └── collection.yaml +</code></pre><h4 id="collectionyaml"><code>collection.yaml</code></h4> +<p>We define here two packages with a collection. They will share the same compilation spec to generate two different packages + + + + + +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">packages</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div> + +<small> <i class='fab fa-github'></i> <i>Complete source code: <a target=_blank href="https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/collection.yaml">https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/collection.yaml</a></i> </small> +<hr> +</p> +<h4 id="writefileyaml"><code>writefile.yaml</code></h4> +<p>All the files in the <code>templates</code> folder will get rendered by the template for each package in the tree. We define here a simple block to write out a file from the context which is passed by: + + + + + +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml">{{<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">define &#34;writefile&#34; }}</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#000">echo conflict &gt; /foo/{{.}}</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>{{<span style="color:#000">end}}</span></code></pre></div> + +<small> <i class='fab fa-github'></i> <i>Complete source code: <a target=_blank href="https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/templates/writefile.yaml">https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/templates/writefile.yaml</a></i> </small> +<hr> +</p> +<h4 id="buildyaml"><code>build.yaml</code></h4> +<p>Finally the build spec consumes the template block we declared above, passing by the name of the package: + + + + + +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">image</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;alpine&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">prelude</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span>- <span style="color:#000">mkdir /foo</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">steps</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>{{<span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">template &#34;writefile&#34; .Values.name }}</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">package_dir</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">/foo</span></code></pre></div> + +<small> <i class='fab fa-github'></i> <i>Complete source code: <a target=_blank href="https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/build.yaml">https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/build.yaml</a></i> </small> +<hr> +</p> +<h2 id="limitations">Limitations</h2> +<p>The <code>finalize.yaml</code> file has access only to the package fields during templating. Extra fields that are present in the <code>definition.yaml</code> file are <em>not</em> accessible during rendering in the <code>finalize.yaml</code> file, but only the package fields (<code>name</code>, <code>version</code>, <code>labels</code>, <code>annotations</code>, &hellip;)</p> +<h2 id="references">References</h2> +<ul> +<li><a href="http://masterminds.github.io/sprig/">Sprig docs</a></li> +<li><a href="https://helm.sh/docs/chart_template_guide/function_list/">Helm Templating functions</a></li> +<li><a href="https://helm.sh/docs/chart_template_guide/variables/">Helm Templating variable</a></li> +</ul> +<h2 id="examples">Examples</h2> +<ul> +<li><a href="https://github.com/mocaccinoOS/mocaccino-musl-universe/tree/master/multi-arch/packages/tar">https://github.com/mocaccinoOS/mocaccino-musl-universe/tree/master/multi-arch/packages/tar</a></li> +</ul> + + + + + + Docs: ARM images + https://luet-lab.github.io/docs/docs/resources/arm/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/resources/arm/ + + + + + +<div class="alert alert-warning" role="alert"> +<h4 class="alert-heading">Warning</h4> + + This article is outdated. +Please refer to the <a href="../../tutorials/hello_world/">&ldquo;Hello World&rdquo;</a> tutorial instead. + +</div> + +<p>Here we show an example on how to build &ldquo;burnable&rdquo; SD images for Raspberry Pi with Luet. This approach lets you describe and version OTA upgrades for your embedded devices, delivering upgrades as layer upgrades on the Pi.</p> +<p>The other good side of the medal is that you can build a Luet package repository with multiple distributions (e.g. <code>Raspbian</code>, <code>OpenSUSE</code>, <code>Gentoo</code>, &hellip; ) and switch among them in runtime. In the above example <code>Raspbian</code> and <code>Funtoo</code> (at the time of writing) are available.</p> +<h2 id="prerequisites">Prerequisites</h2> +<p>You have to run the following steps inside an ARM board to produce arm-compatible binaries. Any distribution with Docker will work. Note that the same steps could be done in a cross-compilation approach, or with qemu-binfmt in a amd64 host.</p> +<p>You will also need in your host:</p> +<ul> +<li>Docker</li> +<li>Luet installed (+container-diff) in <code>/usr/bin/luet</code> (arm build)</li> +<li>make</li> +</ul> +<h2 id="build-the-packages">Build the packages</h2> +<p>Clone the repository <a href="https://github.com/Luet-lab/luet-embedded">https://github.com/Luet-lab/luet-embedded</a></p> +<pre><code>$&gt; git clone https://github.com/Luet-lab/luet-embedded +$&gt; cd luet-embedded +$&gt; sudo make build-all +... +</code></pre> +<p>If a rebuild is needed, just do <code>sudo make rebuild-all</code> after applying the changes.</p> +<h2 id="create-the-repository">Create the repository</h2> +<pre><code>$&gt; sudo make create-repo +... +</code></pre> +<h2 id="serve-the-repo-locally">Serve the repo locally</h2> +<pre><code>$&gt; make serve-repo +... +</code></pre> +<h2 id="create-the-flashable-image">Create the flashable image</h2> +<h3 id="funtoo-based-system">Funtoo based system</h3> +<pre><code>$&gt; sudo LUET_PACKAGES='distro/funtoo-1.4 distro/raspbian-boot-0.20191208 system/luet-develop-0.5' make image +... +</code></pre> +<h3 id="raspbian-based-system">Raspbian based system</h3> +<pre><code>$&gt; sudo LUET_PACKAGES='distro/raspbian-0.20191208 distro/raspbian-boot-0.20191208 system/luet-develop-0.5' make image +... +</code></pre> +<p>At the end of the process, a file <code>luet_os.img</code>, ready to be flashed to an SD card, should be present in the current directory.</p> +<h2 id="add-packages">Add packages</h2> +<p>In order to build and add <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/">packages</a> to the exiting repository, simply add or edit the <a href="https://luet-lab.github.io/docs/docs/docs/concepts/specfile">specfiles</a> under the <code>distro</code> folder. When doing <code>make rebuild-all</code> the packages will be automatically compiled and made available to the local repository.</p> + + + + + + Docs: Building + https://luet-lab.github.io/docs/docs/resources/building/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/resources/building/ + + + + <h2 id="simple-package-build">Simple package build</h2> +<p>Creating and building a simple <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/">package</a>:</p> +<pre tabindex="0"><code>$&gt; mkdir package + +$&gt; cat &lt;&lt;EOF &gt; package/build.yaml +image: busybox +steps: +- echo &quot;foo&quot; &gt; /foo +EOF + +$&gt; cat &lt;&lt;EOF &gt; package/definition.yaml +name: &quot;foo&quot; +version: &quot;0.1&quot; +EOF + +$&gt; luet build --all + +📦 Selecting foo 0.1 +📦 Compiling foo version 0.1 .... ☕ +🐋 Downloading image luet/cache-foo-bar-0.1-builder +🐋 Downloading image luet/cache-foo-bar-0.1 +📦 foo Generating 🐋 definition for builder image from busybox +🐋 Building image luet/cache-foo-bar-0.1-builder +🐋 Building image luet/cache-foo-bar-0.1-builder done + Sending build context to Docker daemon 4.096kB + ... + +</code></pre><h3 id="build-packages">Build packages</h3> +<p>In order to build a specific version, a full <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/">package</a> definition (triple of <code>category</code>, <code>name</code> and <code>version</code>) has to be specified. +In this example we will also enable package compression (gzip).</p> +<pre tabindex="0"><code>$&gt; mkdir package + +$&gt; cat &lt;&lt;EOF &gt; package/build.yaml +image: busybox +steps: +- echo &quot;foo&quot; &gt; /foo +EOF + +$&gt; cat &lt;&lt;EOF &gt; package/definition.yaml +name: &quot;foo&quot; +version: &quot;0.1&quot; +category: &quot;bar&quot; +EOF + +$&gt; luet build bar/foo-0.1 --compression gzip + +📦 Selecting foo 0.1 +📦 Compiling foo version 0.1 .... ☕ +🐋 Downloading image luet/cache-foo-bar-0.1-builder +🐋 Downloading image luet/cache-foo-bar-0.1 +📦 foo Generating 🐋 definition for builder image from busybox +🐋 Building image luet/cache-foo-bar-0.1-builder +🐋 Building image luet/cache-foo-bar-0.1-builder done + Sending build context to Docker daemon 4.096kB + ... + +</code></pre> + + + + + Docs: Collections + https://luet-lab.github.io/docs/docs/concepts/packages/collections/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/packages/collections/ + + + + <p><code>Collections</code> are a special superset of packages. To define a collection, instead of using a <code>definition.yaml</code> file, create a <code>collection.yaml</code> file with a list of packages:</p> + + + + + +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#204a87;font-weight:bold">packages</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;foo&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"></span>- <span style="color:#204a87;font-weight:bold">category</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;test&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">name</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;bar&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">version</span><span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">&#34;1.0&#34;</span><span style="color:#f8f8f8;text-decoration:underline"> +</span></code></pre></div> + +<small> <i class='fab fa-github'></i> <i>Complete source code: <a target=_blank href="https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/collection.yaml">https://github.com/mudler/luet/blob/master/tests/fixtures/shared_templates/test/collection.yaml</a></i> </small> +<hr> + +<p>Packages under a collection shares the same <code>build.yaml</code> and <code>finalize.yaml</code>, so a typical package layout can be:</p> +<pre tabindex="0"><code>collection/ + collection.yaml + build.yaml + finalize.yaml + ... additional files in the build context +</code></pre><p>Luet during the build phase, will treat packages of a collection individually. A collection is a way to share the same build process across different packages.</p> +<h2 id="templating">Templating</h2> +<p><a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/templates">The templating mechanism</a> can be used in collections as well, and each stanza in <code>packages</code> is used to interpolate each single package.</p> +<h2 id="examples">Examples</h2> +<ul> +<li><a href="https://github.com/mocaccinoOS/mocaccino-musl-universe/tree/master/multi-arch/packages/entities">https://github.com/mocaccinoOS/mocaccino-musl-universe/tree/master/multi-arch/packages/entities</a></li> +<li><a href="https://github.com/mocaccinoOS/portage-tree/tree/master/multi-arch/packages/groups">https://github.com/mocaccinoOS/portage-tree/tree/master/multi-arch/packages/groups</a></li> +<li><a href="https://github.com/mocaccinoOS/mocaccino-musl-universe/tree/master/multi-arch/packages/X">https://github.com/mocaccinoOS/mocaccino-musl-universe/tree/master/multi-arch/packages/X</a></li> +</ul> + + + + + + Docs: CSP, SAT && RL + https://luet-lab.github.io/docs/docs/concepts/overview/constraints/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/concepts/overview/constraints/ + + + + <p>Under the hood, Luet uses boolean satisfiability problem (<a href="https://en.wikipedia.org/wiki/Boolean_satisfiability_problem">SAT</a>) <a href="https://en.wikipedia.org/wiki/Reinforcement_learning">reinforcement learning</a> techniques to solve package constraints.</p> +<p>Luet allows you to specify 3 types of set of contraints on a <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/">package</a> definition:</p> +<ul> +<li>Requires</li> +<li>Conflicts</li> +<li>Provides</li> +</ul> +<p>The package definition in your tree definition, along with its Requires and Conflicts, are turned into Boolean formulas that are consumed by the solver to compute a solution. The solution represent the state of your system after a particular query is asked to the solver (Install, Uninstall, Upgrade).</p> +<h2 id="requires-and-conflicts">Requires and Conflicts</h2> +<p>A list of requires and conflicts, composed of one or more <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/">packages</a>, becomes a SAT formula. The formula is then given to the SAT solver to compute a finite state set of packages which must be installed in the system in order to met the requirements.</p> +<p>As Luet allows to express constraints with selectors ( e.g. <code>A depends on &gt;=B-1.0</code>) it generates additional constraints to guarantee that at least one package and at most one is picked as dependency (<em>ALO</em> and <em>AMO</em>).</p> +<h2 id="provides">Provides</h2> +<p>Provides constraints are not encoded in a SAT formula. Instead, they are <code>expanded</code> into an in-place substitution of the packages that they have to be replaced with. +They share the same SAT logic of expansion, allowing to swap entire version ranges (e.g. <code>&gt;=1.0</code>), allowing to handle package rename, removals, and virtuals.</p> +<h2 id="references">References</h2> +<ul> +<li>OPIUM (Luet is inspired by it): <a href="https://ranjitjhala.github.io/static/opium.pdf">https://ranjitjhala.github.io/static/opium.pdf</a></li> +<li>FROM TRACTABLE CSP TO TRACTABLE SAT: <a href="https://www.cs.ox.ac.uk/files/4014/maxclosed_orderencoding_v16_TR.pdf">https://www.cs.ox.ac.uk/files/4014/maxclosed_orderencoding_v16_TR.pdf</a></li> +<li>Solver concepts applied to packages (<code>zypper</code>): <a href="https://en.opensuse.org/openSUSE:Libzypp_satsolver_basics">https://en.opensuse.org/openSUSE:Libzypp_satsolver_basics</a></li> +</ul> + + + + + + Docs: Frequently Asked Questions + https://luet-lab.github.io/docs/docs/resources/faq/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/resources/faq/ + + + + <h2 id="cant-build-packages">Can&rsquo;t build packages</h2> +<p>There might be several reasons why packages fails to build, for example, if your build fails like this:</p> +<pre tabindex="0"><code>$ luet build ... + + INFO Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? + ERROR Error: Failed compiling development/toolchain-go-0.6: failed building package image: Could not push image: quay.io/mocaccino/micro-toolchain:latest toolchain-go-development-0.6-builder.dockerfile: Could not build image: quay.io/mocaccino/micro-toolchain:latest toolchain-go-development-0.6-builder.dockerfile: Failed running command: : exit status 1 + ERROR Bailing out +</code></pre><p>means the user you are running the build command can&rsquo;t either connect to docker or <code>docker</code> is not started.</p> +<p>Check if the user you are running the build is in the <code>docker</code> group, or if the <code>docker</code> daemon is started.</p> +<p>Luet by default if run with multiple packages summarize errors and can be difficult to navigate to logs, but if you think you might have found a bug, run the build with <code>--debug</code> before opening an issue.</p> +<h2 id="why-the-name-luet">Why the name <code>luet</code>?</h2> +<p>Well, I have the idea that programs should be small, so they are not difficult to type and easy to remember, and easy to stick in. <code>luet</code> is really a combination of the first letters of my fiancee name (Lucia) and my name (Ettore) <code>lu+et = luet</code>! and besides, happen to be also a <a href="http://www.comuniterrae.it/punto/ponte-luet/">small bridge</a> in Italy ;)</p> + + + + + + Docs: Images from scratch + https://luet-lab.github.io/docs/docs/resources/scratch/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/resources/scratch/ + + + + <p>The Docker image <code>quay.io/luet/base</code> is a <code>scratch</code> Docker image always kept up-to-date with the latest luet version. That image can be used to bootstrap new images with Luet repositories with the packages you want, from the repositories you prefer.</p> +<p>For example we can mount a config file, and later on install a package:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; $PWD/luet.yaml +</span><span style="color:#4e9a06">repositories: +</span><span style="color:#4e9a06"> - name: &#34;micro-stable&#34; +</span><span style="color:#4e9a06"> enable: true +</span><span style="color:#4e9a06"> cached: true +</span><span style="color:#4e9a06"> priority: 1 +</span><span style="color:#4e9a06"> type: &#34;http&#34; +</span><span style="color:#4e9a06"> urls: +</span><span style="color:#4e9a06"> - &#34;https://get.mocaccino.org/mocaccino-micro-stable&#34; +</span><span style="color:#4e9a06">EOF</span> + +docker rm luet-runtime-test <span style="color:#ce5c00;font-weight:bold">||</span> <span style="color:#204a87">true</span> +docker run --name luet-runtime-test <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span> -ti -v /tmp:/tmp <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span> -v <span style="color:#000">$PWD</span>/luet.yaml:/etc/luet/luet.yaml:ro <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span> quay.io/luet/base install shells/bash + +docker commit luet-runtime-test luet-runtime-test-image + +<span style="color:#8f5902;font-style:italic"># Try your new image!</span> + +docker run -ti --entrypoint /bin/bash --rm luet-runtime-test-image +</code></pre></div><p>In this way we will create a new image, with only <code>luet</code> and <code>bash</code>, and nothing else from a scratch image.</p> + + + + + + Docs: References + https://luet-lab.github.io/docs/docs/resources/references/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/resources/references/ + + + + <h2 id="references">References</h2> +<p>Here is a list of references to projects that are related to Luet (open up a PR to add yours to the list!):</p> +<table> +<thead> +<tr> +<th>Description</th> +<th>URL</th> +</tr> +</thead> +<tbody> +<tr> +<td>Official Luet repository</td> +<td><a href="https://github.com/Luet-lab/luet-repo">https://github.com/Luet-lab/luet-repo</a></td> +</tr> +<tr> +<td>Example repository to host package browser websites on gh-pages. It uses the package-browser extension to generate HTML pages from a list of luet repositories</td> +<td><a href="https://github.com/Luet-lab/package-browser-sample">https://github.com/Luet-lab/package-browser-sample</a></td> +</tr> +<tr> +<td>LineageOS builds with luet</td> +<td><a href="https://github.com/mudler/android-builds">https://github.com/mudler/android-builds</a></td> +</tr> +<tr> +<td>Example repository template to build packages on github actions and push packages on a container registry</td> +<td><a href="https://github.com/Luet-lab/github-repository">https://github.com/Luet-lab/github-repository</a></td> +</tr> +<tr> +<td>Immutable container OS toolkit</td> +<td><a href="https://github.com/rancher-sandbox/cOS-toolkit">https://github.com/rancher-sandbox/cOS-toolkit</a></td> +</tr> +<tr> +<td>mocaccinoOS desktop</td> +<td><a href="https://github.com/mocaccinoOS/desktop">https://github.com/mocaccinoOS/desktop</a></td> +</tr> +<tr> +<td>mocaccinoOS extra</td> +<td><a href="https://github.com/mocaccinoOS/mocaccino-extra">https://github.com/mocaccinoOS/mocaccino-extra</a></td> +</tr> +</tbody> +</table> + + + + + + Docs: Contributing + https://luet-lab.github.io/docs/docs/contribution-guidelines/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/contribution-guidelines/ + + + + <h2 id="contributing-to-luet">Contributing to Luet</h2> +<p>Contribution guidelines for the Luet project are on the <a href="https://github.com/mudler/luet/blob/master/CONTRIBUTING.md">Github repository</a>. Here you can find some heads up for contributing to the documentation website.</p> +<h2 id="contributing-to-the-docs-website">Contributing to the Docs website</h2> +<h3 id="we-develop-with-github">We Develop with Github</h3> +<p>We use <a href="https://github.com/Luet-lab/docs">github to host code</a>, to track issues and feature requests, as well as accept pull requests.</p> +<p>We use <a href="https://gohugo.io/">Hugo</a> to format and generate our website, the +<a href="https://github.com/google/docsy">Docsy</a> theme for styling and site structure, +and Github Actions to manage the deployment of the site. +Hugo is an open-source static site generator that provides us with templates, +content organisation in a standard directory structure, and a website generation +engine. You write the pages in Markdown (or HTML if you want), and Hugo wraps them up into a website.</p> +<p>All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. Consult +<a href="https://help.github.com/articles/about-pull-requests/">GitHub Help</a> for more +information on using pull requests.</p> +<h3 id="any-contributions-you-make-will-be-under-the-software-license-of-the-repository">Any contributions you make will be under the Software License of the repository</h3> +<p>In short, when you submit code changes, your submissions are understood to be under the same License that covers the project. Feel free to contact the maintainers if that&rsquo;s a concern.</p> +<h3 id="updating-a-single-page">Updating a single page</h3> +<p>If you&rsquo;ve just spotted something you&rsquo;d like to change while using the docs, Docsy has a shortcut for you:</p> +<ol> +<li>Click <strong>Edit this page</strong> in the top right hand corner of the page you want to modify.</li> +<li>If you don&rsquo;t already have an up to date fork of the project repo, you are prompted to get one - click <strong>Fork this repository and propose changes</strong> or <strong>Update your Fork</strong> to get an up to date version of the project to edit. The appropriate page in your fork is displayed in edit mode.</li> +</ol> +<h3 id="quick-start-with-a-local-checkout">Quick start with a local checkout</h3> +<p>Here&rsquo;s a quick guide to updating the docs with a git local checkout. It assumes you&rsquo;re familiar with the +GitHub workflow and you&rsquo;re happy to use the automated preview of your doc +updates:</p> +<ol> +<li>Fork the <a href="https://github.com/Luet-lab/docs">the Docs repo</a> on GitHub.</li> +<li>Make your changes, to see the preview run <code>make serve</code> and browse to <code>localhost:1313</code></li> +<li>If you&rsquo;re not yet ready for a review, add &ldquo;WIP&rdquo; to the PR name to indicate +it&rsquo;s a work in progress.</li> +<li>Continue updating your doc and pushing your changes until you&rsquo;re happy with +the content.</li> +<li>When you&rsquo;re ready for a review, add a comment to the PR, and remove any +&ldquo;WIP&rdquo; markers.</li> +<li>When you are satisfied send a pull request (PR).</li> +</ol> +<h3 id="license">License</h3> +<p>By contributing, you agree that your contributions will be licensed under the project Licenses.</p> + + + + + + diff --git a/docs/resources/arm/index.html b/docs/resources/arm/index.html new file mode 100644 index 00000000..ef604679 --- /dev/null +++ b/docs/resources/arm/index.html @@ -0,0 +1,534 @@ + + + + + + + + + + + + + + + + + + + + +ARM images | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

ARM images

+
Use Luet to build, track, and release OTA update for your embedded devices.
+ + + + + +

Here we show an example on how to build “burnable” SD images for Raspberry Pi with Luet. This approach lets you describe and version OTA upgrades for your embedded devices, delivering upgrades as layer upgrades on the Pi.

+

The other good side of the medal is that you can build a Luet package repository with multiple distributions (e.g. Raspbian, OpenSUSE, Gentoo, … ) and switch among them in runtime. In the above example Raspbian and Funtoo (at the time of writing) are available.

+

Prerequisites

+

You have to run the following steps inside an ARM board to produce arm-compatible binaries. Any distribution with Docker will work. Note that the same steps could be done in a cross-compilation approach, or with qemu-binfmt in a amd64 host.

+

You will also need in your host:

+
    +
  • Docker
  • +
  • Luet installed (+container-diff) in /usr/bin/luet (arm build)
  • +
  • make
  • +
+

Build the packages

+

Clone the repository https://github.com/Luet-lab/luet-embedded

+
$> git clone https://github.com/Luet-lab/luet-embedded
+$> cd luet-embedded
+$> sudo make build-all
+...
+
+

If a rebuild is needed, just do sudo make rebuild-all after applying the changes.

+

Create the repository

+
$> sudo make create-repo
+...
+
+

Serve the repo locally

+
$> make serve-repo
+...
+
+

Create the flashable image

+

Funtoo based system

+
$> sudo LUET_PACKAGES='distro/funtoo-1.4 distro/raspbian-boot-0.20191208 system/luet-develop-0.5' make image
+...
+
+

Raspbian based system

+
$> sudo LUET_PACKAGES='distro/raspbian-0.20191208 distro/raspbian-boot-0.20191208 system/luet-develop-0.5' make image
+...
+
+

At the end of the process, a file luet_os.img, ready to be flashed to an SD card, should be present in the current directory.

+

Add packages

+

In order to build and add packages to the exiting repository, simply add or edit the specfiles under the distro folder. When doing make rebuild-all the packages will be automatically compiled and made available to the local repository.

+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/resources/building/index.html b/docs/resources/building/index.html new file mode 100644 index 00000000..22584abb --- /dev/null +++ b/docs/resources/building/index.html @@ -0,0 +1,536 @@ + + + + + + + + + + + + + + + + + + + + +Building | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Building

+
Examples to build with Luet
+ +

Simple package build

+

Creating and building a simple package:

+
$> mkdir package
+
+$> cat <<EOF > package/build.yaml
+image: busybox
+steps:
+- echo "foo" > /foo
+EOF
+
+$> cat <<EOF > package/definition.yaml
+name: "foo"
+version: "0.1"
+EOF
+
+$> luet build --all
+
+📦  Selecting  foo 0.1
+📦  Compiling foo version 0.1 .... ☕
+🐋  Downloading image luet/cache-foo-bar-0.1-builder
+🐋  Downloading image luet/cache-foo-bar-0.1
+📦   foo Generating 🐋  definition for builder image from busybox
+🐋  Building image luet/cache-foo-bar-0.1-builder
+🐋  Building image luet/cache-foo-bar-0.1-builder done
+ Sending build context to Docker daemon  4.096kB
+ ...
+
+

Build packages

+

In order to build a specific version, a full package definition (triple of category, name and version) has to be specified. +In this example we will also enable package compression (gzip).

+
$> mkdir package
+
+$> cat <<EOF > package/build.yaml
+image: busybox
+steps:
+- echo "foo" > /foo
+EOF
+
+$> cat <<EOF > package/definition.yaml
+name: "foo"
+version: "0.1"
+category: "bar"
+EOF
+
+$> luet build bar/foo-0.1 --compression gzip
+
+📦  Selecting  foo 0.1
+📦  Compiling foo version 0.1 .... ☕
+🐋  Downloading image luet/cache-foo-bar-0.1-builder
+🐋  Downloading image luet/cache-foo-bar-0.1
+📦   foo Generating 🐋  definition for builder image from busybox
+🐋  Building image luet/cache-foo-bar-0.1-builder
+🐋  Building image luet/cache-foo-bar-0.1-builder done
+ Sending build context to Docker daemon  4.096kB
+ ...
+
+
+ + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/resources/faq/index.html b/docs/resources/faq/index.html new file mode 100644 index 00000000..0eb904aa --- /dev/null +++ b/docs/resources/faq/index.html @@ -0,0 +1,489 @@ + + + + + + + + + + + + + + + + + + + + +Frequently Asked Questions | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Frequently Asked Questions

+
FAQ
+ +

Can’t build packages

+

There might be several reasons why packages fails to build, for example, if your build fails like this:

+
$ luet build ...
+
+ INFO   Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
+  ERROR    Error: Failed compiling development/toolchain-go-0.6: failed building package image: Could not push image: quay.io/mocaccino/micro-toolchain:latest toolchain-go-development-0.6-builder.dockerfile: Could not build image: quay.io/mocaccino/micro-toolchain:latest toolchain-go-development-0.6-builder.dockerfile: Failed running command: : exit status 1
+  ERROR    Bailing out
+

means the user you are running the build command can’t either connect to docker or docker is not started.

+

Check if the user you are running the build is in the docker group, or if the docker daemon is started.

+

Luet by default if run with multiple packages summarize errors and can be difficult to navigate to logs, but if you think you might have found a bug, run the build with --debug before opening an issue.

+

Why the name luet?

+

Well, I have the idea that programs should be small, so they are not difficult to type and easy to remember, and easy to stick in. luet is really a combination of the first letters of my fiancee name (Lucia) and my name (Ettore) lu+et = luet! and besides, happen to be also a small bridge in Italy ;)

+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/resources/index.html b/docs/resources/index.html new file mode 100644 index 00000000..ea457911 --- /dev/null +++ b/docs/resources/index.html @@ -0,0 +1,519 @@ + + + + + + + + + + + + + + + + + + + + + +Resources | Luet + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Resources

+
Luet examples, resources, API reference
+ + +
+ + + + + + + + +
+ + +
+
+ ARM images +
+

Use Luet to build, track, and release OTA update for your embedded devices.

+
+ + +
+
+ Building +
+

Examples to build with Luet

+
+ + +
+
+ Frequently Asked Questions +
+

FAQ

+
+ + +
+
+ Images from scratch +
+

Using Luet to compose images from scratch

+
+ + +
+
+ References +
+

References to various resources related to luet

+
+ + +
+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/resources/index.xml b/docs/resources/index.xml new file mode 100644 index 00000000..a2907256 --- /dev/null +++ b/docs/resources/index.xml @@ -0,0 +1,264 @@ + + + Luet – Resources + https://luet-lab.github.io/docs/docs/resources/ + Recent content in Resources on Luet + Hugo -- gohugo.io + Thu, 05 Jan 2017 00:00:00 +0000 + + + + + + + + + + + Docs: ARM images + https://luet-lab.github.io/docs/docs/resources/arm/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/resources/arm/ + + + + + +<div class="alert alert-warning" role="alert"> +<h4 class="alert-heading">Warning</h4> + + This article is outdated. +Please refer to the <a href="../../tutorials/hello_world/">&ldquo;Hello World&rdquo;</a> tutorial instead. + +</div> + +<p>Here we show an example on how to build &ldquo;burnable&rdquo; SD images for Raspberry Pi with Luet. This approach lets you describe and version OTA upgrades for your embedded devices, delivering upgrades as layer upgrades on the Pi.</p> +<p>The other good side of the medal is that you can build a Luet package repository with multiple distributions (e.g. <code>Raspbian</code>, <code>OpenSUSE</code>, <code>Gentoo</code>, &hellip; ) and switch among them in runtime. In the above example <code>Raspbian</code> and <code>Funtoo</code> (at the time of writing) are available.</p> +<h2 id="prerequisites">Prerequisites</h2> +<p>You have to run the following steps inside an ARM board to produce arm-compatible binaries. Any distribution with Docker will work. Note that the same steps could be done in a cross-compilation approach, or with qemu-binfmt in a amd64 host.</p> +<p>You will also need in your host:</p> +<ul> +<li>Docker</li> +<li>Luet installed (+container-diff) in <code>/usr/bin/luet</code> (arm build)</li> +<li>make</li> +</ul> +<h2 id="build-the-packages">Build the packages</h2> +<p>Clone the repository <a href="https://github.com/Luet-lab/luet-embedded">https://github.com/Luet-lab/luet-embedded</a></p> +<pre><code>$&gt; git clone https://github.com/Luet-lab/luet-embedded +$&gt; cd luet-embedded +$&gt; sudo make build-all +... +</code></pre> +<p>If a rebuild is needed, just do <code>sudo make rebuild-all</code> after applying the changes.</p> +<h2 id="create-the-repository">Create the repository</h2> +<pre><code>$&gt; sudo make create-repo +... +</code></pre> +<h2 id="serve-the-repo-locally">Serve the repo locally</h2> +<pre><code>$&gt; make serve-repo +... +</code></pre> +<h2 id="create-the-flashable-image">Create the flashable image</h2> +<h3 id="funtoo-based-system">Funtoo based system</h3> +<pre><code>$&gt; sudo LUET_PACKAGES='distro/funtoo-1.4 distro/raspbian-boot-0.20191208 system/luet-develop-0.5' make image +... +</code></pre> +<h3 id="raspbian-based-system">Raspbian based system</h3> +<pre><code>$&gt; sudo LUET_PACKAGES='distro/raspbian-0.20191208 distro/raspbian-boot-0.20191208 system/luet-develop-0.5' make image +... +</code></pre> +<p>At the end of the process, a file <code>luet_os.img</code>, ready to be flashed to an SD card, should be present in the current directory.</p> +<h2 id="add-packages">Add packages</h2> +<p>In order to build and add <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/">packages</a> to the exiting repository, simply add or edit the <a href="https://luet-lab.github.io/docs/docs/docs/concepts/specfile">specfiles</a> under the <code>distro</code> folder. When doing <code>make rebuild-all</code> the packages will be automatically compiled and made available to the local repository.</p> + + + + + + Docs: Building + https://luet-lab.github.io/docs/docs/resources/building/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/resources/building/ + + + + <h2 id="simple-package-build">Simple package build</h2> +<p>Creating and building a simple <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/">package</a>:</p> +<pre tabindex="0"><code>$&gt; mkdir package + +$&gt; cat &lt;&lt;EOF &gt; package/build.yaml +image: busybox +steps: +- echo &quot;foo&quot; &gt; /foo +EOF + +$&gt; cat &lt;&lt;EOF &gt; package/definition.yaml +name: &quot;foo&quot; +version: &quot;0.1&quot; +EOF + +$&gt; luet build --all + +📦 Selecting foo 0.1 +📦 Compiling foo version 0.1 .... ☕ +🐋 Downloading image luet/cache-foo-bar-0.1-builder +🐋 Downloading image luet/cache-foo-bar-0.1 +📦 foo Generating 🐋 definition for builder image from busybox +🐋 Building image luet/cache-foo-bar-0.1-builder +🐋 Building image luet/cache-foo-bar-0.1-builder done + Sending build context to Docker daemon 4.096kB + ... + +</code></pre><h3 id="build-packages">Build packages</h3> +<p>In order to build a specific version, a full <a href="https://luet-lab.github.io/docs/docs/docs/concepts/packages/">package</a> definition (triple of <code>category</code>, <code>name</code> and <code>version</code>) has to be specified. +In this example we will also enable package compression (gzip).</p> +<pre tabindex="0"><code>$&gt; mkdir package + +$&gt; cat &lt;&lt;EOF &gt; package/build.yaml +image: busybox +steps: +- echo &quot;foo&quot; &gt; /foo +EOF + +$&gt; cat &lt;&lt;EOF &gt; package/definition.yaml +name: &quot;foo&quot; +version: &quot;0.1&quot; +category: &quot;bar&quot; +EOF + +$&gt; luet build bar/foo-0.1 --compression gzip + +📦 Selecting foo 0.1 +📦 Compiling foo version 0.1 .... ☕ +🐋 Downloading image luet/cache-foo-bar-0.1-builder +🐋 Downloading image luet/cache-foo-bar-0.1 +📦 foo Generating 🐋 definition for builder image from busybox +🐋 Building image luet/cache-foo-bar-0.1-builder +🐋 Building image luet/cache-foo-bar-0.1-builder done + Sending build context to Docker daemon 4.096kB + ... + +</code></pre> + + + + + Docs: Frequently Asked Questions + https://luet-lab.github.io/docs/docs/resources/faq/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/resources/faq/ + + + + <h2 id="cant-build-packages">Can&rsquo;t build packages</h2> +<p>There might be several reasons why packages fails to build, for example, if your build fails like this:</p> +<pre tabindex="0"><code>$ luet build ... + + INFO Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? + ERROR Error: Failed compiling development/toolchain-go-0.6: failed building package image: Could not push image: quay.io/mocaccino/micro-toolchain:latest toolchain-go-development-0.6-builder.dockerfile: Could not build image: quay.io/mocaccino/micro-toolchain:latest toolchain-go-development-0.6-builder.dockerfile: Failed running command: : exit status 1 + ERROR Bailing out +</code></pre><p>means the user you are running the build command can&rsquo;t either connect to docker or <code>docker</code> is not started.</p> +<p>Check if the user you are running the build is in the <code>docker</code> group, or if the <code>docker</code> daemon is started.</p> +<p>Luet by default if run with multiple packages summarize errors and can be difficult to navigate to logs, but if you think you might have found a bug, run the build with <code>--debug</code> before opening an issue.</p> +<h2 id="why-the-name-luet">Why the name <code>luet</code>?</h2> +<p>Well, I have the idea that programs should be small, so they are not difficult to type and easy to remember, and easy to stick in. <code>luet</code> is really a combination of the first letters of my fiancee name (Lucia) and my name (Ettore) <code>lu+et = luet</code>! and besides, happen to be also a <a href="http://www.comuniterrae.it/punto/ponte-luet/">small bridge</a> in Italy ;)</p> + + + + + + Docs: Images from scratch + https://luet-lab.github.io/docs/docs/resources/scratch/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/resources/scratch/ + + + + <p>The Docker image <code>quay.io/luet/base</code> is a <code>scratch</code> Docker image always kept up-to-date with the latest luet version. That image can be used to bootstrap new images with Luet repositories with the packages you want, from the repositories you prefer.</p> +<p>For example we can mount a config file, and later on install a package:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; $PWD/luet.yaml +</span><span style="color:#4e9a06">repositories: +</span><span style="color:#4e9a06"> - name: &#34;micro-stable&#34; +</span><span style="color:#4e9a06"> enable: true +</span><span style="color:#4e9a06"> cached: true +</span><span style="color:#4e9a06"> priority: 1 +</span><span style="color:#4e9a06"> type: &#34;http&#34; +</span><span style="color:#4e9a06"> urls: +</span><span style="color:#4e9a06"> - &#34;https://get.mocaccino.org/mocaccino-micro-stable&#34; +</span><span style="color:#4e9a06">EOF</span> + +docker rm luet-runtime-test <span style="color:#ce5c00;font-weight:bold">||</span> <span style="color:#204a87">true</span> +docker run --name luet-runtime-test <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span> -ti -v /tmp:/tmp <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span> -v <span style="color:#000">$PWD</span>/luet.yaml:/etc/luet/luet.yaml:ro <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span> quay.io/luet/base install shells/bash + +docker commit luet-runtime-test luet-runtime-test-image + +<span style="color:#8f5902;font-style:italic"># Try your new image!</span> + +docker run -ti --entrypoint /bin/bash --rm luet-runtime-test-image +</code></pre></div><p>In this way we will create a new image, with only <code>luet</code> and <code>bash</code>, and nothing else from a scratch image.</p> + + + + + + Docs: References + https://luet-lab.github.io/docs/docs/resources/references/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/resources/references/ + + + + <h2 id="references">References</h2> +<p>Here is a list of references to projects that are related to Luet (open up a PR to add yours to the list!):</p> +<table> +<thead> +<tr> +<th>Description</th> +<th>URL</th> +</tr> +</thead> +<tbody> +<tr> +<td>Official Luet repository</td> +<td><a href="https://github.com/Luet-lab/luet-repo">https://github.com/Luet-lab/luet-repo</a></td> +</tr> +<tr> +<td>Example repository to host package browser websites on gh-pages. It uses the package-browser extension to generate HTML pages from a list of luet repositories</td> +<td><a href="https://github.com/Luet-lab/package-browser-sample">https://github.com/Luet-lab/package-browser-sample</a></td> +</tr> +<tr> +<td>LineageOS builds with luet</td> +<td><a href="https://github.com/mudler/android-builds">https://github.com/mudler/android-builds</a></td> +</tr> +<tr> +<td>Example repository template to build packages on github actions and push packages on a container registry</td> +<td><a href="https://github.com/Luet-lab/github-repository">https://github.com/Luet-lab/github-repository</a></td> +</tr> +<tr> +<td>Immutable container OS toolkit</td> +<td><a href="https://github.com/rancher-sandbox/cOS-toolkit">https://github.com/rancher-sandbox/cOS-toolkit</a></td> +</tr> +<tr> +<td>mocaccinoOS desktop</td> +<td><a href="https://github.com/mocaccinoOS/desktop">https://github.com/mocaccinoOS/desktop</a></td> +</tr> +<tr> +<td>mocaccinoOS extra</td> +<td><a href="https://github.com/mocaccinoOS/mocaccino-extra">https://github.com/mocaccinoOS/mocaccino-extra</a></td> +</tr> +</tbody> +</table> + + + + + + diff --git a/docs/resources/references/index.html b/docs/resources/references/index.html new file mode 100644 index 00000000..ec477ae0 --- /dev/null +++ b/docs/resources/references/index.html @@ -0,0 +1,506 @@ + + + + + + + + + + + + + + + + + + + + +References | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

References

+
References to various resources related to luet
+ +

References

+

Here is a list of references to projects that are related to Luet (open up a PR to add yours to the list!):

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionURL
Official Luet repositoryhttps://github.com/Luet-lab/luet-repo
Example repository to host package browser websites on gh-pages. It uses the package-browser extension to generate HTML pages from a list of luet repositorieshttps://github.com/Luet-lab/package-browser-sample
LineageOS builds with luethttps://github.com/mudler/android-builds
Example repository template to build packages on github actions and push packages on a container registryhttps://github.com/Luet-lab/github-repository
Immutable container OS toolkithttps://github.com/rancher-sandbox/cOS-toolkit
mocaccinoOS desktophttps://github.com/mocaccinoOS/desktop
mocaccinoOS extrahttps://github.com/mocaccinoOS/mocaccino-extra
+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/resources/scratch/index.html b/docs/resources/scratch/index.html new file mode 100644 index 00000000..4950d39c --- /dev/null +++ b/docs/resources/scratch/index.html @@ -0,0 +1,495 @@ + + + + + + + + + + + + + + + + + + + + +Images from scratch | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Images from scratch

+
Using Luet to compose images from scratch
+ +

The Docker image quay.io/luet/base is a scratch Docker image always kept up-to-date with the latest luet version. That image can be used to bootstrap new images with Luet repositories with the packages you want, from the repositories you prefer.

+

For example we can mount a config file, and later on install a package:

+
cat <<EOF > $PWD/luet.yaml  
+repositories: 
+  - name: "micro-stable"
+    enable: true
+    cached: true
+    priority: 1
+    type: "http"
+    urls: 
+    - "https://get.mocaccino.org/mocaccino-micro-stable"
+EOF
+
+docker rm luet-runtime-test || true
+docker run --name luet-runtime-test \
+       -ti -v /tmp:/tmp \
+       -v $PWD/luet.yaml:/etc/luet/luet.yaml:ro \
+       quay.io/luet/base install shells/bash
+ 
+docker commit luet-runtime-test luet-runtime-test-image
+
+# Try your new image!
+
+docker run -ti --entrypoint /bin/bash --rm luet-runtime-test-image
+

In this way we will create a new image, with only luet and bash, and nothing else from a scratch image.

+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/tutorials/build_package/index.html b/docs/tutorials/build_package/index.html new file mode 100644 index 00000000..254fcf47 --- /dev/null +++ b/docs/tutorials/build_package/index.html @@ -0,0 +1,668 @@ + + + + + + + + + + + + + + + + + + + + +Build a package | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Build a package

+
Example on how to build a package and run it locally with luet box
+ + + + + +

catclock

+

Catclock example

+

In this example, we will build the awesome CatClock on containers we will run it locally in a Luet box.

+

We will do this experiment to prove two things:

+
    +
  1. how we can build a package with Luet and
  2. +
  3. two packages from different distributions can (sometime) work together.
  4. +
+

Prerequisites

+

To build packages with Luet, you must have installed Docker and container-diff, follow our setup guide.

+

1) Create the package

+

To prove our point, we will build our package from an OpenSUSE image, and later on we will consume +entropy repositories for runtime dependencies. To note, this is not the main focus of Luet, and this is a restricted example on its features on build-time resolution. For more syntax examples, see also Build specs and Package types.

+

Run this commands in any directory you choose to be your workspace:

+

+# Let's create a directory to store our package spec:
+mkdir -p tree/misc/catclock/
+

1.1) Build spec

+

Now, let’s generate our build spec:

+
# Create a build file. We use here opensuse/leap to build the package, as an example
+cat <<EOF > tree/misc/catclock/build.yaml
+image: opensuse/leap
+
+# Preparation phase
+prelude:
+- zypper in -y git make libXt-devel xmh gcc motif-devel libXext-devel libpulse-devel libaubio-devel
+- git clone https://github.com/BarkyTheDog/catclock
+
+# Here we define the steps that Luet will follow
+steps:
+- cd catclock && make DEFINES="-Wno-incompatible-pointer-types"
+- mv catclock/xclock /usr/bin/xclock
+
+# (optional) File list that will be included in the final package
+# Luet will filter out files that won't match any entry in the list (regex syntax IS supported)
+includes:
+- /usr/bin/xclock
+EOF
+
+

build.yaml is what an ebuild is for Gentoo and for e.g. what PKGBUILD is for Arch.

+
    +
  • image: opensuse/leap tells luet to use opensuse/leap as a build image. We collect the build time dependencies with zypper (the openSUSE package manager), and the CatClock with git. When we declare an image keyword in a spec, it becomes a seed package ( Package types ) as doesn’t depend on any package in build time, we will cover more use cases in other examples.
  • +
  • prelude is a list of commands that will happen during the build phase. +They might generate binaries, or download sources, but those are not took into consideration when generating the final package.
  • +
  • steps is a list of commands that will happen during the build phase. +Luet will execute those commands and all the binaries generated from them become part of the final package
  • +
  • includes is a (optional) list of regex that tells to Luet what files to filter out from the final artifact.
  • +
+

1.2) Runtime spec

+

Now we generate the runtime spec, it’s the part about the binary end which will be installed in the system. It also holds the metadata relative to the package definition (name, category, version).

+
# Create a runtime definition.
+# We will leverage packages already present on Sabayon Entropy repositories
+# the end-system needs to have the Luet Sabayon Entropy repositories enabled.
+cat <<EOF > tree/misc/catclock/definition.yaml
+category: "misc"
+name: "catclock"
+version: "0.20200318"
+requires:
+- category: meta
+  name: users
+  version: ">=0"
+- category: x11-libs
+  name: motif
+  version: ">=0.1"
+- category: media-libs
+  name: libjpeg-turbo
+  version: ">=0.1"
+EOF
+
    +
  • category, name, and version: identifies the package in a Luet tree. This is the unique identifier for a package.
  • +
  • requires it’s a list of packages which our catclock depends on during runtime (when we will execute catclock inside a small-container!). To find out what’s required by your binaries it can be a try-learn-fail effort. If the package you wish to build is specifying the deps it requires, and those are available in a Luet repository, you are all set, just point them there. Otherwise you have to figure out after you build the binary the first time (for example, with ldd) to which libraries it depends on. +In this example we consume the dependencies from the Luet Entropy Repo, that we will enable on the following steps.
  • +
+

2) Build it!

+
sudo /usr/bin/luet build \
+--tree=$PWD/tree misc/catclock \
+--destination $PWD/build \
+--compression gzip
+
+sudo chown -R $USER $PWD/build # So later on, we can access to the repository with our user
+

We are building the specs in this step.

+
    +
  • tree: is the path where our specs are, in our case it’s tree.
  • +
  • destination: is the path where our packages will be stored, in our case this is build.
  • +
  • compression: is the compression algorithm used to compress the final artifacts
  • +
+

Note, we need sudo to keep the permissions properly mapped in the artifact which is produced +this is not always the case. Depends on the package content.

+

3) Create a local repository

+

We will generate now our repository metadata:

+
/usr/bin/luet create-repo --tree "tree" \
+--output $PWD/build \
+--packages $PWD/build \
+--name "test repo" \
+--descr "Test Repo" \
+--tree-compression gzip \
+--meta-compression gzip
+

Creating a repository in Luet is about adding metadata and make our spec tree available to other systems running Luet to intall the package.

+
    +
  • output: a path which is where Luet will store the repository metadata.
  • +
  • packages: a path containing the packages that were built during the build step
  • +
  • name: Repository name
  • +
  • descr: Repository description
  • +
  • tree-compression: optional, algorithm to use when compression the tree metadata
  • +
  • meta-compression: optional, algorithm to use when compression the repository metadata
  • +
+

4) Let’s test it!

+

Now we are all set. We have the packages compiled, and we are ready to consume them. We don’t want to break our host system, and we want to test this from our user.

+

Let’s create a directory, we will try to setup a full running system, and install everything there.

+
# Let's create a directory for our "fake" rootfilesystem
+# it will be populated with a minimal set of packages needed to run 
+# our amazing catclock
+mkdir -p $PWD/rootfs
+
# Let's also create a directory to store our config files
+mkdir -p $PWD/conf
+

We will generate now a Luet config. The Luet config is used to read where install things from, and in which directory. +It also lists the repositories that are used by the client to retrieve packages remotely.

+
# We create here a config file which references the rootfs.
+# In this way, luet instead installing packages to your host system, will populate the rootfs
+# (note, all the steps are run by a user here, no root required!)
+cat <<EOF > conf/luet-dso-local.yaml
+system:
+  rootfs: $PWD/rootfs # our "fake" rootfs that we created before
+  database_path: "/" # this is where our Luet DB will live
+  database_engine: "boltdb" # this is the Luet DB engine
+repositories:
+   - name: "main"
+     type: "disk"
+     priority: 3
+     enable: true
+     urls:
+       - "$PWD/build" # This is the repository we have created before!
+   - name: "sabayonlinux.org"
+     description: "Sabayon Linux Repository"
+     type: "http"
+     enable: true
+     cached: true
+     priority: 2
+     urls:
+       - "https://dispatcher.sabayon.org/sbi/namespace/luet-entropy-repo"
+   - name: "luet-repo"
+     description: "Luet Official Repository"
+     type: "http"
+     enable: true
+     cached: true
+     priority: 1
+     urls:
+       - "https://raw.githubusercontent.com/Luet-lab/luet-repo/gh-pages"
+EOF
+# we have specified an additional repository, one that is luet-entropy-repo (which contains
+# the runtime dependencies we specified in our package)
+
# Let's populate our rootfs with some minimal things: base-gcc, and bash
+# meta/users is a meta package providing minimal base to run things with a full
+# user-level support.
+export LUET_NOLOCK=true
+luet install \
+--config $PWD/conf/luet-dso-local.yaml \
+meta/users
+
# catclock is a X11 app! we want to be able to play with it locally from our host :)
+# Let's copy the .Xauthority file to allow the X app to communicate with our X server
+# Note: This can be achieved in other ways (set up a tcp X server, and so on)
+cp -rfv $HOME/.Xauthority $PWD/rootfs/                                                        
+
luet install \
+--config $PWD/conf/luet-dso-local.yaml \
+misc/catclock
+
# Let's run our beautiful catclock :)
+luet box exec --rootfs $PWD/rootfs \
+--stdin --stdout --stderr --env DISPLAY=$DISPLAY \
+--env XAUTHORITY=/.Xauthority --mount /tmp --entrypoint /usr/bin/xclock
+

Spawn a bash shell inside our box (with permission to access to our running X):

+
luet box exec --rootfs $PWD/rootfs \
+--stdin --stdout --stderr --env DISPLAY=$DISPLAY \
+--env XAUTHORITY=/.Xauthority --mount /tmp --entrypoint /bin/bash
+
+ + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/tutorials/hello_world/index.html b/docs/tutorials/hello_world/index.html new file mode 100644 index 00000000..418d0fc7 --- /dev/null +++ b/docs/tutorials/hello_world/index.html @@ -0,0 +1,553 @@ + + + + + + + + + + + + + + + + + + + + +Hello world! | Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Hello world!

+
Everything starts from an “Hello!”
+ +

This article will guide you to build your first package with Luet! +For this purpose, we have picked a real-world example: gogs which is a “painless self-hosted Git service”, an open-source alternative to Github.

+

Gogs is written in Golang, and we need a working Golang version in order to build it.

+

Here you can see a live recorded session of this tutorial:

+ +

Define a Luet tree

+

Everything starts from a Luet tree. A Luet tree is just a directory containing one (or more) Luet specfile, here on we assume that you are working in a dedicated folder (e.g. ~/demo) in your system.

+

Let’s create then a package that will be our base to build other packages from now on, we have picked busybox here - it is really small and enough for our purpose.

+

busybox

+
mkdir busybox
+

Let’s now write the build specification, which is just containing the image tag that we are referencing to

+
cat <<EOF > busybox/build.yaml
+image: "busybox:{{.Values.version}}-glibc"
+EOF
+

Now, lets write the definition.yaml, which contains the metadata information about our package ( e.g. how we refer to it with luet, the version, and so on )

+
cat <<EOF > busybox/definition.yaml
+category: "distro"
+name: "busybox"
+version: "1.33.0"
+EOF
+

golang

+

We need now golang in order to build gogs. Let’s declare then a golang package:

+
mkdir golang
+

And a build specfile, which is simply fetch golang from https://golang.org and installing it in the busybox container:

+
cat <<EOF > golang/build.yaml
+requires:
+- category: "distro"
+  name: "busybox"
+  version: ">=0"
+
+prelude:
+- wget https://golang.org/dl/go{{.Values.version}}.linux-{{.Values.arch}}.tar.gz -O golang.tar.gz
+- mkdir /usr/local
+steps:
+- tar -C /usr/local -xzf golang.tar.gz
+EOF
+

Note how we require busybox. The Golang container will now be based from busybox, and the prelude and steps fields will be executed in that context.

+

And finally let’s write the golang metadata files, so we can refer to it from other packages

+
cat <<EOF > golang/definition.yaml
+name: "go"
+category: "dev-lang"
+version: "1.15.6"
+arch: "amd64"
+EOF
+

gogs

+

Finally we can write the gogs package definition!

+
mkdir gogs
+

The build specfile, will just fetch the gogs sources at a given version (specified in the definition.yaml) and build the sources with go:

+
cat <<'EOF' > gogs/build.yaml
+requires:
+- category: "dev-lang"
+  name: "go"
+  version: ">=0"
+env:
+- GOPATH="/go"
+- GOGSPATH="$GOPATH/src/github.com/gogs/gogs"
+- PATH=$PATH:/usr/local/go/bin
+- CGO_ENABLED=0
+prelude:
+- mkdir -p $GOPATH/src/github.com/gogs
+- wget https://github.com/gogs/gogs/archive/v{{.Values.version}}.tar.gz -O - | tar -xzf - -C ./  && mv gogs-{{.Values.version}} $GOGSPATH
+steps:
+- mkdir /usr/bin
+- cd $GOGSPATH && go build && mv gogs /usr/bin/gogs
+excludes:
+# Cache generated by Golang
+- ^/root
+EOF
+

And the metadata, in this way we can refer to gogs in a Luet tree:

+
cat <<EOF > gogs/definition.yaml
+category: "dev-vcs"
+name: "gogs"
+version: "0.11.91"
+EOF
+

Build packages

+

The simplest and mostly immediate way to build packages, is running luet build <packagename> in the same folder you have your Luet tree.

+

In this case, to build gogs and its deps, we can do:

+
luet build dev-vcs/gogs
+

And that’s it! you will find the package archives in build/ in the same folder where you started the command.

+

You will see that Luet generates not only archives with the file resulting to your builds, but it will also generate metadata files (ending with .metadata.yaml) that contains additional metadata information about your build and the package itself (e.g. checksums).

+

You can use tools like yq to inspect those:

+
yq r build/gogs-dev-vcs-0.11.91.metadata.yaml checksums
+

Now if you want to consume the artifacts just built with luet install, you can create a repository with luet create-repo.

+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ + +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/tutorials/index.html b/docs/tutorials/index.html new file mode 100644 index 00000000..76e84afb --- /dev/null +++ b/docs/tutorials/index.html @@ -0,0 +1,495 @@ + + + + + + + + + + + + + + + + + + + + + +Tutorials | Luet + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+ + +
+ + + + + +
+

Tutorials

+
Howtos, Cookbooks
+ + +
+ + + + + + + + +
+ + +
+
+ Hello world! +
+

Everything starts from an “Hello!”

+
+ + +
+
+ Build a package +
+

Example on how to build a package and run it locally with luet box

+
+ + +
+ + + +
+ + + + + + +
+ + +
+ + +
+ Last modified January 30, 2022: :notebook: Add docs alongside (91fd5b0) +
+ +
+ +
+
+
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/tutorials/index.xml b/docs/tutorials/index.xml new file mode 100644 index 00000000..edd64a52 --- /dev/null +++ b/docs/tutorials/index.xml @@ -0,0 +1,310 @@ + + + Luet – Tutorials + https://luet-lab.github.io/docs/docs/tutorials/ + Recent content in Tutorials on Luet + Hugo -- gohugo.io + Wed, 04 Jan 2017 00:00:00 +0000 + + + + + + + + + + + Docs: Hello world! + https://luet-lab.github.io/docs/docs/tutorials/hello_world/ + Wed, 04 Jan 2017 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/tutorials/hello_world/ + + + + <p>This article will guide you to build your first package with Luet! +For this purpose, we have picked a real-world example: <a href="https://github.com/gogs/gogs">gogs</a> which is a &ldquo;painless self-hosted Git service&rdquo;, an open-source alternative to Github.</p> +<p>Gogs is written in Golang, and we need a working Golang version in order to build it.</p> +<p>Here you can see a live recorded session of this tutorial:</p> +<script id="asciicast-388348" src="https://asciinema.org/a/388348.js" data-autoplay="true" data-size="small" data-cols="120" data-rows="40" async></script> +<h1 id="define-a-luet-tree">Define a Luet tree</h1> +<p>Everything starts from a Luet tree. A Luet tree is just a directory containing one (or more) Luet specfile, here on we assume that you are working in a dedicated folder (e.g. <code>~/demo</code>) in your system.</p> +<p>Let&rsquo;s create then a package that will be our base to build other packages from now on, we have picked <code>busybox</code> here - it is really small and enough for our purpose.</p> +<h2 id="busybox">busybox</h2> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">mkdir busybox +</code></pre></div><p>Let&rsquo;s now write the build specification, which is just containing the image tag that we are referencing to</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; busybox/build.yaml +</span><span style="color:#4e9a06">image: &#34;busybox:{{.Values.version}}-glibc&#34; +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><p>Now, lets write the <code>definition.yaml</code>, which contains the metadata information about our package ( e.g. how we refer to it with luet, the version, and so on )</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; busybox/definition.yaml +</span><span style="color:#4e9a06">category: &#34;distro&#34; +</span><span style="color:#4e9a06">name: &#34;busybox&#34; +</span><span style="color:#4e9a06">version: &#34;1.33.0&#34; +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><h2 id="golang">golang</h2> +<p>We need now golang in order to build <code>gogs</code>. Let&rsquo;s declare then a golang package:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">mkdir golang +</code></pre></div><p>And a build specfile, which is simply fetch golang from <a href="https://golang.org">https://golang.org</a> and installing it in the busybox container:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; golang/build.yaml +</span><span style="color:#4e9a06">requires: +</span><span style="color:#4e9a06">- category: &#34;distro&#34; +</span><span style="color:#4e9a06"> name: &#34;busybox&#34; +</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34; +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06">prelude: +</span><span style="color:#4e9a06">- wget https://golang.org/dl/go{{.Values.version}}.linux-{{.Values.arch}}.tar.gz -O golang.tar.gz +</span><span style="color:#4e9a06">- mkdir /usr/local +</span><span style="color:#4e9a06">steps: +</span><span style="color:#4e9a06">- tar -C /usr/local -xzf golang.tar.gz +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><p>Note how we <code>require</code> busybox. The Golang container will now be based from busybox, and the <code>prelude</code> and <code>steps</code> fields will be executed in that context.</p> +<p>And finally let&rsquo;s write the golang metadata files, so we can refer to it from other packages</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; golang/definition.yaml +</span><span style="color:#4e9a06">name: &#34;go&#34; +</span><span style="color:#4e9a06">category: &#34;dev-lang&#34; +</span><span style="color:#4e9a06">version: &#34;1.15.6&#34; +</span><span style="color:#4e9a06">arch: &#34;amd64&#34; +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><h2 id="gogs">gogs</h2> +<p>Finally we can write the gogs package definition!</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">mkdir gogs +</code></pre></div><p>The build specfile, will just fetch the <code>gogs</code> sources at a given version (specified in the <code>definition.yaml</code>) and build the sources with go:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;&#39;EOF&#39; &gt; gogs/build.yaml +</span><span style="color:#4e9a06">requires: +</span><span style="color:#4e9a06">- category: &#34;dev-lang&#34; +</span><span style="color:#4e9a06"> name: &#34;go&#34; +</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34; +</span><span style="color:#4e9a06">env: +</span><span style="color:#4e9a06">- GOPATH=&#34;/go&#34; +</span><span style="color:#4e9a06">- GOGSPATH=&#34;$GOPATH/src/github.com/gogs/gogs&#34; +</span><span style="color:#4e9a06">- PATH=$PATH:/usr/local/go/bin +</span><span style="color:#4e9a06">- CGO_ENABLED=0 +</span><span style="color:#4e9a06">prelude: +</span><span style="color:#4e9a06">- mkdir -p $GOPATH/src/github.com/gogs +</span><span style="color:#4e9a06">- wget https://github.com/gogs/gogs/archive/v{{.Values.version}}.tar.gz -O - | tar -xzf - -C ./ &amp;&amp; mv gogs-{{.Values.version}} $GOGSPATH +</span><span style="color:#4e9a06">steps: +</span><span style="color:#4e9a06">- mkdir /usr/bin +</span><span style="color:#4e9a06">- cd $GOGSPATH &amp;&amp; go build &amp;&amp; mv gogs /usr/bin/gogs +</span><span style="color:#4e9a06">excludes: +</span><span style="color:#4e9a06"># Cache generated by Golang +</span><span style="color:#4e9a06">- ^/root +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><p>And the metadata, in this way we can refer to gogs in a Luet tree:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; gogs/definition.yaml +</span><span style="color:#4e9a06">category: &#34;dev-vcs&#34; +</span><span style="color:#4e9a06">name: &#34;gogs&#34; +</span><span style="color:#4e9a06">version: &#34;0.11.91&#34; +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><h1 id="build-packages">Build packages</h1> +<p>The simplest and mostly immediate way to build packages, is running <code>luet build &lt;packagename&gt;</code> in the same folder you have your Luet tree.</p> +<p>In this case, to build gogs and its deps, we can do:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">luet build dev-vcs/gogs +</code></pre></div><p>And that&rsquo;s it! you will find the package archives in <code>build/</code> in the same folder where you started the command.</p> +<p>You will see that Luet generates not only archives with the file resulting to your builds, but it will also generate metadata files (ending with <code>.metadata.yaml</code>) that contains additional metadata information about your build and the package itself (e.g. checksums).</p> +<p>You can use tools like <a href="https://github.com/mikefarah/yq">yq</a> to inspect those:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">yq r build/gogs-dev-vcs-0.11.91.metadata.yaml checksums +</code></pre></div><p>Now if you want to consume the artifacts just built with <code>luet install</code>, you can create a repository with <code>luet create-repo</code>.</p> + + + + + + Docs: Build a package + https://luet-lab.github.io/docs/docs/tutorials/build_package/ + Wed, 04 Jan 2017 00:00:00 +0000 + + https://luet-lab.github.io/docs/docs/tutorials/build_package/ + + + + + +<div class="alert alert-warning" role="alert"> +<h4 class="alert-heading">Warning</h4> + + This article contains references to Luet repositories that were deprecated, and needs to be updated. +Please refer to the <a href="../../tutorials/hello_world/">&ldquo;Hello World&rdquo;</a> tutorial instead. + +</div> + +<p><img src="https://github.com/BarkyTheDog/catclock/raw/master/catclock.gif" alt="catclock"></p> +<h1 id="catclock-example">Catclock example</h1> +<p>In this example, we will build the awesome <a href="https://github.com/BarkyTheDog/catclock">CatClock</a> on containers we will run it locally in a Luet box.</p> +<p>We will do this experiment to prove two things:</p> +<ol> +<li>how we can build a package with Luet and</li> +<li>two packages from different distributions can (sometime) work together.</li> +</ol> +<h2 id="prerequisites">Prerequisites</h2> +<p>To build packages with Luet, you must have installed Docker and container-diff, follow our <a href="../../getting-started">setup guide</a>.</p> +<h2 id="1-create-the-package">1) Create the package</h2> +<p>To prove our point, we will build our package from an OpenSUSE image, and later on we will consume +entropy repositories for runtime dependencies. To note, this is not the main focus of Luet, and this is a restricted example on its features on build-time resolution. For more syntax examples, see also <a href="../../concepts/specfile/#build-specs">Build specs</a> and <a href="../../concepts/packages/#package-types">Package types</a>.</p> +<p>Run this commands in any directory you choose to be your workspace:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"> +<span style="color:#8f5902;font-style:italic"># Let&#39;s create a directory to store our package spec:</span> +mkdir -p tree/misc/catclock/ +</code></pre></div><h3 id="11-build-spec">1.1) Build spec</h3> +<p>Now, let&rsquo;s generate our <strong>build</strong> spec:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># Create a build file. We use here opensuse/leap to build the package, as an example</span> +cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; tree/misc/catclock/build.yaml +</span><span style="color:#4e9a06">image: opensuse/leap +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06"># Preparation phase +</span><span style="color:#4e9a06">prelude: +</span><span style="color:#4e9a06">- zypper in -y git make libXt-devel xmh gcc motif-devel libXext-devel libpulse-devel libaubio-devel +</span><span style="color:#4e9a06">- git clone https://github.com/BarkyTheDog/catclock +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06"># Here we define the steps that Luet will follow +</span><span style="color:#4e9a06">steps: +</span><span style="color:#4e9a06">- cd catclock &amp;&amp; make DEFINES=&#34;-Wno-incompatible-pointer-types&#34; +</span><span style="color:#4e9a06">- mv catclock/xclock /usr/bin/xclock +</span><span style="color:#4e9a06"> +</span><span style="color:#4e9a06"># (optional) File list that will be included in the final package +</span><span style="color:#4e9a06"># Luet will filter out files that won&#39;t match any entry in the list (regex syntax IS supported) +</span><span style="color:#4e9a06">includes: +</span><span style="color:#4e9a06">- /usr/bin/xclock +</span><span style="color:#4e9a06">EOF</span> + +</code></pre></div><p><code>build.yaml</code> is what an ebuild is for Gentoo and for e.g. what PKGBUILD is for Arch.</p> +<ul> +<li><em>image: opensuse/leap</em> tells luet to use opensuse/leap as a build image. We collect the build time dependencies with <code>zypper</code> (the openSUSE package manager), and the <a href="https://github.com/BarkyTheDog/catclock">CatClock</a> with <code>git</code>. When we declare an <code>image</code> keyword in a spec, it becomes a <em>seed</em> package ( <a href="../../concepts/packages/#package-types">Package types</a> ) as doesn&rsquo;t depend on any package in build time, we will cover more use cases in other examples.</li> +<li><em>prelude</em> is a list of commands that will happen during the build phase. +They might generate binaries, or download sources, but those are not took into consideration when generating the final package.</li> +<li><em>steps</em> is a list of commands that will happen during the build phase. +Luet will execute those commands and all the binaries generated from them become part of the final package</li> +<li><em>includes</em> is a (optional) list of regex that tells to Luet what files to filter out from the final artifact.</li> +</ul> +<h3 id="12-runtime-spec">1.2) Runtime spec</h3> +<p>Now we generate the runtime spec, it&rsquo;s the part about the binary end which will be installed in the system. It also holds the metadata relative to the package definition (<code>name</code>, <code>category</code>, <code>version</code>).</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># Create a runtime definition.</span> +<span style="color:#8f5902;font-style:italic"># We will leverage packages already present on Sabayon Entropy repositories</span> +<span style="color:#8f5902;font-style:italic"># the end-system needs to have the Luet Sabayon Entropy repositories enabled.</span> +cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; tree/misc/catclock/definition.yaml +</span><span style="color:#4e9a06">category: &#34;misc&#34; +</span><span style="color:#4e9a06">name: &#34;catclock&#34; +</span><span style="color:#4e9a06">version: &#34;0.20200318&#34; +</span><span style="color:#4e9a06">requires: +</span><span style="color:#4e9a06">- category: meta +</span><span style="color:#4e9a06"> name: users +</span><span style="color:#4e9a06"> version: &#34;&gt;=0&#34; +</span><span style="color:#4e9a06">- category: x11-libs +</span><span style="color:#4e9a06"> name: motif +</span><span style="color:#4e9a06"> version: &#34;&gt;=0.1&#34; +</span><span style="color:#4e9a06">- category: media-libs +</span><span style="color:#4e9a06"> name: libjpeg-turbo +</span><span style="color:#4e9a06"> version: &#34;&gt;=0.1&#34; +</span><span style="color:#4e9a06">EOF</span> +</code></pre></div><ul> +<li><em>category</em>, <em>name</em>, and <em>version</em>: identifies the package in a Luet tree. This is the unique identifier for a package.</li> +<li><em>requires</em> it&rsquo;s a list of packages which our <strong>catclock</strong> depends on during runtime (when we will execute catclock inside a small-container!). To find out what&rsquo;s required by your binaries it can be a try-learn-fail effort. If the package you wish to build is specifying the deps it requires, and those are available in a Luet repository, you are all set, just point them there. Otherwise you have to figure out after you build the binary the first time (for example, with <code>ldd</code>) to which libraries it depends on. +In this example we consume the dependencies from the <a href="https://github.com/Luet-lab/luet-entropy-repo">Luet Entropy Repo</a>, that we will enable on the following steps.</li> +</ul> +<h2 id="2-build-it">2) Build it!</h2> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">sudo /usr/bin/luet build <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--tree<span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">$PWD</span>/tree misc/catclock <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--destination <span style="color:#000">$PWD</span>/build <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--compression gzip + +sudo chown -R <span style="color:#000">$USER</span> <span style="color:#000">$PWD</span>/build <span style="color:#8f5902;font-style:italic"># So later on, we can access to the repository with our user</span> +</code></pre></div><p>We are building the specs in this step.</p> +<ul> +<li><em>tree</em>: is the path where our specs are, in our case it&rsquo;s <code>tree</code>.</li> +<li><em>destination</em>: is the path where our packages will be stored, in our case this is <code>build</code>.</li> +<li><em>compression</em>: is the compression algorithm used to compress the final artifacts</li> +</ul> +<p>Note, we need <em>sudo</em> to keep the permissions properly mapped in the artifact which is produced +this is not always the case. Depends on the package content.</p> +<h2 id="3-create-a-local-repository">3) Create a local repository</h2> +<p>We will generate now our repository metadata:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">/usr/bin/luet create-repo --tree <span style="color:#4e9a06">&#34;tree&#34;</span> <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--output <span style="color:#000">$PWD</span>/build <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--packages <span style="color:#000">$PWD</span>/build <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--name <span style="color:#4e9a06">&#34;test repo&#34;</span> <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--descr <span style="color:#4e9a06">&#34;Test Repo&#34;</span> <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--tree-compression gzip <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--meta-compression gzip +</code></pre></div><p>Creating a repository in Luet is about adding metadata and make our spec tree available to other systems running Luet to intall the package.</p> +<ul> +<li><strong>output</strong>: a path which is where Luet will store the repository metadata.</li> +<li><strong>packages</strong>: a path containing the packages that were built during the build step</li> +<li><strong>name</strong>: Repository name</li> +<li><strong>descr</strong>: Repository description</li> +<li><strong>tree-compression</strong>: optional, algorithm to use when compression the tree metadata</li> +<li><strong>meta-compression</strong>: optional, algorithm to use when compression the repository metadata</li> +</ul> +<h2 id="4-lets-test-it">4) Let&rsquo;s test it!</h2> +<p>Now we are all set. We have the packages compiled, and we are ready to consume them. We don&rsquo;t want to break our host system, and we want to test this from our user.</p> +<p>Let&rsquo;s create a directory, we will try to setup a full running system, and install everything there.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># Let&#39;s create a directory for our &#34;fake&#34; rootfilesystem</span> +<span style="color:#8f5902;font-style:italic"># it will be populated with a minimal set of packages needed to run </span> +<span style="color:#8f5902;font-style:italic"># our amazing catclock</span> +mkdir -p <span style="color:#000">$PWD</span>/rootfs +</code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># Let&#39;s also create a directory to store our config files</span> +mkdir -p <span style="color:#000">$PWD</span>/conf +</code></pre></div><p>We will generate now a Luet config. The Luet config is used to read where install things from, and in which directory. +It also lists the repositories that are used by the client to retrieve packages remotely.</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># We create here a config file which references the rootfs.</span> +<span style="color:#8f5902;font-style:italic"># In this way, luet instead installing packages to your host system, will populate the rootfs</span> +<span style="color:#8f5902;font-style:italic"># (note, all the steps are run by a user here, no root required!)</span> +cat <span style="color:#4e9a06">&lt;&lt;EOF &gt; conf/luet-dso-local.yaml +</span><span style="color:#4e9a06">system: +</span><span style="color:#4e9a06"> rootfs: $PWD/rootfs # our &#34;fake&#34; rootfs that we created before +</span><span style="color:#4e9a06"> database_path: &#34;/&#34; # this is where our Luet DB will live +</span><span style="color:#4e9a06"> database_engine: &#34;boltdb&#34; # this is the Luet DB engine +</span><span style="color:#4e9a06">repositories: +</span><span style="color:#4e9a06"> - name: &#34;main&#34; +</span><span style="color:#4e9a06"> type: &#34;disk&#34; +</span><span style="color:#4e9a06"> priority: 3 +</span><span style="color:#4e9a06"> enable: true +</span><span style="color:#4e9a06"> urls: +</span><span style="color:#4e9a06"> - &#34;$PWD/build&#34; # This is the repository we have created before! +</span><span style="color:#4e9a06"> - name: &#34;sabayonlinux.org&#34; +</span><span style="color:#4e9a06"> description: &#34;Sabayon Linux Repository&#34; +</span><span style="color:#4e9a06"> type: &#34;http&#34; +</span><span style="color:#4e9a06"> enable: true +</span><span style="color:#4e9a06"> cached: true +</span><span style="color:#4e9a06"> priority: 2 +</span><span style="color:#4e9a06"> urls: +</span><span style="color:#4e9a06"> - &#34;https://dispatcher.sabayon.org/sbi/namespace/luet-entropy-repo&#34; +</span><span style="color:#4e9a06"> - name: &#34;luet-repo&#34; +</span><span style="color:#4e9a06"> description: &#34;Luet Official Repository&#34; +</span><span style="color:#4e9a06"> type: &#34;http&#34; +</span><span style="color:#4e9a06"> enable: true +</span><span style="color:#4e9a06"> cached: true +</span><span style="color:#4e9a06"> priority: 1 +</span><span style="color:#4e9a06"> urls: +</span><span style="color:#4e9a06"> - &#34;https://raw.githubusercontent.com/Luet-lab/luet-repo/gh-pages&#34; +</span><span style="color:#4e9a06">EOF</span> +<span style="color:#8f5902;font-style:italic"># we have specified an additional repository, one that is luet-entropy-repo (which contains</span> +<span style="color:#8f5902;font-style:italic"># the runtime dependencies we specified in our package)</span> +</code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># Let&#39;s populate our rootfs with some minimal things: base-gcc, and bash</span> +<span style="color:#8f5902;font-style:italic"># meta/users is a meta package providing minimal base to run things with a full</span> +<span style="color:#8f5902;font-style:italic"># user-level support.</span> +<span style="color:#204a87">export</span> <span style="color:#000">LUET_NOLOCK</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#204a87">true</span> +luet install <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--config <span style="color:#000">$PWD</span>/conf/luet-dso-local.yaml <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>meta/users +</code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># catclock is a X11 app! we want to be able to play with it locally from our host :)</span> +<span style="color:#8f5902;font-style:italic"># Let&#39;s copy the .Xauthority file to allow the X app to communicate with our X server</span> +<span style="color:#8f5902;font-style:italic"># Note: This can be achieved in other ways (set up a tcp X server, and so on)</span> +cp -rfv <span style="color:#000">$HOME</span>/.Xauthority <span style="color:#000">$PWD</span>/rootfs/ +</code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">luet install <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--config <span style="color:#000">$PWD</span>/conf/luet-dso-local.yaml <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>misc/catclock +</code></pre></div><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#8f5902;font-style:italic"># Let&#39;s run our beautiful catclock :)</span> +luet box <span style="color:#204a87">exec</span> --rootfs <span style="color:#000">$PWD</span>/rootfs <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--stdin --stdout --stderr --env <span style="color:#000">DISPLAY</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">$DISPLAY</span> <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--env <span style="color:#000">XAUTHORITY</span><span style="color:#ce5c00;font-weight:bold">=</span>/.Xauthority --mount /tmp --entrypoint /usr/bin/xclock +</code></pre></div><p>Spawn a bash shell inside our box (with permission to access to our running X):</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">luet box <span style="color:#204a87">exec</span> --rootfs <span style="color:#000">$PWD</span>/rootfs <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--stdin --stdout --stderr --env <span style="color:#000">DISPLAY</span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#000">$DISPLAY</span> <span style="color:#4e9a06">\ +</span><span style="color:#4e9a06"></span>--env <span style="color:#000">XAUTHORITY</span><span style="color:#ce5c00;font-weight:bold">=</span>/.Xauthority --mount /tmp --entrypoint /bin/bash +</code></pre></div> + + + + + diff --git a/favicons/android-144x144.png b/favicons/android-144x144.png new file mode 100755 index 00000000..8851c09a Binary files /dev/null and b/favicons/android-144x144.png differ diff --git a/favicons/android-192x192.png b/favicons/android-192x192.png new file mode 100755 index 00000000..94b2ad2d Binary files /dev/null and b/favicons/android-192x192.png differ diff --git a/favicons/android-36x36.png b/favicons/android-36x36.png new file mode 100755 index 00000000..7ec5cf65 Binary files /dev/null and b/favicons/android-36x36.png differ diff --git a/favicons/android-48x48.png b/favicons/android-48x48.png new file mode 100755 index 00000000..419a445a Binary files /dev/null and b/favicons/android-48x48.png differ diff --git a/favicons/android-72x72.png b/favicons/android-72x72.png new file mode 100755 index 00000000..230b18fd Binary files /dev/null and b/favicons/android-72x72.png differ diff --git a/favicons/android-96x96.png b/favicons/android-96x96.png new file mode 100755 index 00000000..8cc69897 Binary files /dev/null and b/favicons/android-96x96.png differ diff --git a/favicons/apple-touch-icon-180x180.png b/favicons/apple-touch-icon-180x180.png new file mode 100755 index 00000000..03d0b513 Binary files /dev/null and b/favicons/apple-touch-icon-180x180.png differ diff --git a/favicons/favicon-1024.png b/favicons/favicon-1024.png new file mode 100644 index 00000000..920f1072 Binary files /dev/null and b/favicons/favicon-1024.png differ diff --git a/favicons/favicon-16x16.png b/favicons/favicon-16x16.png new file mode 100755 index 00000000..ce918ee3 Binary files /dev/null and b/favicons/favicon-16x16.png differ diff --git a/favicons/favicon-256.png b/favicons/favicon-256.png new file mode 100644 index 00000000..ebd3f8c9 Binary files /dev/null and b/favicons/favicon-256.png differ diff --git a/favicons/favicon-32x32.png b/favicons/favicon-32x32.png new file mode 100755 index 00000000..e95c80ad Binary files /dev/null and b/favicons/favicon-32x32.png differ diff --git a/favicons/favicon.ico b/favicons/favicon.ico new file mode 100755 index 00000000..216330ff Binary files /dev/null and b/favicons/favicon.ico differ diff --git a/favicons/pwa-192x192.png b/favicons/pwa-192x192.png new file mode 100755 index 00000000..94b2ad2d Binary files /dev/null and b/favicons/pwa-192x192.png differ diff --git a/favicons/pwa-512x512.png b/favicons/pwa-512x512.png new file mode 100755 index 00000000..89258a4e Binary files /dev/null and b/favicons/pwa-512x512.png differ diff --git a/favicons/tile150x150.png b/favicons/tile150x150.png new file mode 100755 index 00000000..3d0c7604 Binary files /dev/null and b/favicons/tile150x150.png differ diff --git a/favicons/tile310x150.png b/favicons/tile310x150.png new file mode 100755 index 00000000..ed890428 Binary files /dev/null and b/favicons/tile310x150.png differ diff --git a/favicons/tile310x310.png b/favicons/tile310x310.png new file mode 100755 index 00000000..67172b30 Binary files /dev/null and b/favicons/tile310x310.png differ diff --git a/favicons/tile70x70.png b/favicons/tile70x70.png new file mode 100755 index 00000000..31413a2b Binary files /dev/null and b/favicons/tile70x70.png differ diff --git a/featured-background.jpg b/featured-background.jpg new file mode 100644 index 00000000..6e0dcf5d Binary files /dev/null and b/featured-background.jpg differ diff --git a/featured-background_hu3d03a01dcc18bc5be0e67db3d8d209a6_291319_1920x1080_fill_q75_catmullrom_top.jpg b/featured-background_hu3d03a01dcc18bc5be0e67db3d8d209a6_291319_1920x1080_fill_q75_catmullrom_top.jpg new file mode 100644 index 00000000..0fd29883 Binary files /dev/null and b/featured-background_hu3d03a01dcc18bc5be0e67db3d8d209a6_291319_1920x1080_fill_q75_catmullrom_top.jpg differ diff --git a/featured-background_hu3d03a01dcc18bc5be0e67db3d8d209a6_291319_960x540_fill_q75_catmullrom_top.jpg b/featured-background_hu3d03a01dcc18bc5be0e67db3d8d209a6_291319_960x540_fill_q75_catmullrom_top.jpg new file mode 100644 index 00000000..347013ca Binary files /dev/null and b/featured-background_hu3d03a01dcc18bc5be0e67db3d8d209a6_291319_960x540_fill_q75_catmullrom_top.jpg differ diff --git a/index.html b/index.html new file mode 100644 index 00000000..c5f24d81 --- /dev/null +++ b/index.html @@ -0,0 +1,485 @@ + + + + + + + + + + + + + + + + + + + + + +Luet + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Luet

+ +
+ + +
+ + Documentation + + + Download + +

Container Package Manager

+
+ + + + + +
+
+ + +
+
+
+
+
+ +
+ + + + + + + + +
+
+ + +

Luet uses Container technologies ( Docker, img ) to build packages. +It provides an abstraction over the Dockerfile format introducing relation and versioning of images.

+ + +
+
+
+ + + + + + + +
+
+
+ + +
+
+ +
+

SAT Solver

+
+

Luet uses SAT Solving techniques to compute the dependencies graph. +This allows to refer to docker images by using semver constraints.

+

No Relational db is involved.

+ +
+ +
+ + + +
+
+ +
+

Contributions welcome!

+
+

If you like to play with code, check out our issues that are marked as “good first issue” and open a Pull Request on GitHub. +New users are always welcome, and have fun!

+ +
+

Read more …

+
+ + + +
+
+ +
+

Container-based

+
+

Use container abstraction to define your package repositories

+ +
+ +
+ + + + +
+
+
+ + + + + + + + +
+
+
+ + +
+

Releasing is not anymore a nightmare

+
You can carefully pick now dependencies to make your release - release composed of container images or either of a set of packages +
+
+ + + +
+
+
+ + + + + + + + +
+
+
+ + +
+
+ +
+

Package Management

+
+

Build, ship and delivery your software. Faster

+ +
+ +
+ + + +
+
+ +
+

0 dep installer

+
+

When Luet is used as installer, it has zero dependencies.

+

Your system can’t break anymore

+ +
+ +
+ + + +
+
+ +
+

Reconstruct images

+
+

Thanks to its SAT core, Luet can reconstruct images defined by dependencies and version constraints.

+

Building a de-facto tree of container images

+ +
+ +
+ + + + +
+
+
+ + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/index.json b/index.json new file mode 100644 index 00000000..513322cd --- /dev/null +++ b/index.json @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + +Luet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/index.xml b/index.xml new file mode 100644 index 00000000..394ba6a9 --- /dev/null +++ b/index.xml @@ -0,0 +1,49 @@ + + + Luet – Luet docs + https://luet-lab.github.io/docs/ + Recent content in Luet docs on Luet + Hugo -- gohugo.io + + + + + + + + + + Blog: 0.3 Release + https://luet-lab.github.io/docs/blog/2019/12/23/0.3-release/ + Mon, 23 Dec 2019 00:00:00 +0000 + + https://luet-lab.github.io/docs/blog/2019/12/23/0.3-release/ + + + + <p>This release comes with a lot of bugfixes and enhancement to the SAT solver core:</p> +<ul> +<li>Add support for <code>provides</code>. They allow to have <code>virtual</code> packages which can be replaced during solving by other drop-in packages.</li> +<li>Tons of fixes</li> +<li>Preparation for upcoming compression support</li> +</ul> + + + + + + Blog: Website is up + https://luet-lab.github.io/docs/blog/2019/12/23/website-is-up/ + Mon, 23 Dec 2019 00:00:00 +0000 + + https://luet-lab.github.io/docs/blog/2019/12/23/website-is-up/ + + + + <p>Finally the website is up! Docs are a work in progress. Stay tuned for more upcoming updates</p> + + + + + + diff --git a/install.sh b/install.sh new file mode 100644 index 00000000..0401f207 --- /dev/null +++ b/install.sh @@ -0,0 +1,67 @@ +#!/bin/bash +if [ $(id -u) -ne 0 ] + then echo "Please run the installer with sudo/as root" + exit +fi + +set -ex +export LUET_NOLOCK=true + +LUET_VERSION=${LUET_VERSION:-0.22.7} +LUET_ROOTFS=${LUET_ROOTFS:-/} +LUET_DATABASE_PATH=${LUET_DATABASE_PATH:-/var/luet/db} +LUET_DATABASE_ENGINE=${LUET_DATABASE_ENGINE:-boltdb} +LUET_CONFIG_PROTECT=${LUET_CONFIG_PROTECT:-1} + +if [ -z "$LUET_ARCH" ]; then + LUET_ARCH=$(uname -m) +fi + +case $LUET_ARCH in + amd64|x86_64) + LUET_ARCH=amd64 + ;; + arm64|aarch64|arm*) + LUET_ARCH=armv7 + ;; +esac + +curl -L https://github.com/mudler/luet/releases/download/${LUET_VERSION}/luet-${LUET_VERSION}-linux-${LUET_ARCH} --output luet +chmod +x luet + +mkdir -p /etc/luet/repos.conf.d || true +mkdir -p $LUET_DATABASE_PATH || true +mkdir -p /var/tmp/luet || true + +if [ "${LUET_CONFIG_PROTECT}" = "1" ] ; then + mkdir -p /etc/luet/config.protect.d || true + curl -L https://raw.githubusercontent.com/mudler/luet/master/contrib/config/config.protect.d/01_etc.yml.example --output /etc/luet/config.protect.d/01_etc.yml +fi +curl -L https://raw.githubusercontent.com/mocaccinoOS/repository-index/master/packages/mocaccino-repository-index.yml --output /etc/luet/repos.conf.d/mocaccino-repository-index.yml + +cat > /etc/luet/luet.yaml < +* Version: 1.0.1 +* LastModified: Dec 25 1999 +*/ + +/* Interface: +* data = deflate(src); +*/ +const deflate = (function () { + /* constant parameters */ + var zip_WSIZE = 32768; // Sliding Window size + var zip_STORED_BLOCK = 0; + var zip_STATIC_TREES = 1; + var zip_DYN_TREES = 2; + + /* for deflate */ + var zip_DEFAULT_LEVEL = 6; + var zip_FULL_SEARCH = true; + var zip_INBUFSIZ = 32768; // Input buffer size + var zip_INBUF_EXTRA = 64; // Extra buffer + var zip_OUTBUFSIZ = 1024 * 8; + var zip_window_size = 2 * zip_WSIZE; + var zip_MIN_MATCH = 3; + var zip_MAX_MATCH = 258; + var zip_BITS = 16; + // for SMALL_MEM + var zip_LIT_BUFSIZE = 0x2000; + var zip_HASH_BITS = 13; + // for MEDIUM_MEM + // var zip_LIT_BUFSIZE = 0x4000; + // var zip_HASH_BITS = 14; + // for BIG_MEM + // var zip_LIT_BUFSIZE = 0x8000; + // var zip_HASH_BITS = 15; + //if(zip_LIT_BUFSIZE > zip_INBUFSIZ) + // alert("error: zip_INBUFSIZ is too small"); + //if((zip_WSIZE<<1) > (1< zip_BITS-1) + // alert("error: zip_HASH_BITS is too large"); + //if(zip_HASH_BITS < 8 || zip_MAX_MATCH != 258) + // alert("error: Code too clever"); + var zip_DIST_BUFSIZE = zip_LIT_BUFSIZE; + var zip_HASH_SIZE = 1 << zip_HASH_BITS; + var zip_HASH_MASK = zip_HASH_SIZE - 1; + var zip_WMASK = zip_WSIZE - 1; + var zip_NIL = 0; // Tail of hash chains + var zip_TOO_FAR = 4096; + var zip_MIN_LOOKAHEAD = zip_MAX_MATCH + zip_MIN_MATCH + 1; + var zip_MAX_DIST = zip_WSIZE - zip_MIN_LOOKAHEAD; + var zip_SMALLEST = 1; + var zip_MAX_BITS = 15; + var zip_MAX_BL_BITS = 7; + var zip_LENGTH_CODES = 29; + var zip_LITERALS = 256; + var zip_END_BLOCK = 256; + var zip_L_CODES = zip_LITERALS + 1 + zip_LENGTH_CODES; + var zip_D_CODES = 30; + var zip_BL_CODES = 19; + var zip_REP_3_6 = 16; + var zip_REPZ_3_10 = 17; + var zip_REPZ_11_138 = 18; + var zip_HEAP_SIZE = 2 * zip_L_CODES + 1; + var zip_H_SHIFT = parseInt((zip_HASH_BITS + zip_MIN_MATCH - 1) / + zip_MIN_MATCH); + + /* variables */ + var zip_free_queue; + var zip_qhead, zip_qtail; + var zip_initflag; + var zip_outbuf = null; + var zip_outcnt, zip_outoff; + var zip_complete; + var zip_window; + var zip_d_buf; + var zip_l_buf; + var zip_prev; + var zip_bi_buf; + var zip_bi_valid; + var zip_block_start; + var zip_ins_h; + var zip_hash_head; + var zip_prev_match; + var zip_match_available; + var zip_match_length; + var zip_prev_length; + var zip_strstart; + var zip_match_start; + var zip_eofile; + var zip_lookahead; + var zip_max_chain_length; + var zip_max_lazy_match; + var zip_compr_level; + var zip_good_match; + var zip_nice_match; + var zip_dyn_ltree; + var zip_dyn_dtree; + var zip_static_ltree; + var zip_static_dtree; + var zip_bl_tree; + var zip_l_desc; + var zip_d_desc; + var zip_bl_desc; + var zip_bl_count; + var zip_heap; + var zip_heap_len; + var zip_heap_max; + var zip_depth; + var zip_length_code; + var zip_dist_code; + var zip_base_length; + var zip_base_dist; + var zip_flag_buf; + var zip_last_lit; + var zip_last_dist; + var zip_last_flags; + var zip_flags; + var zip_flag_bit; + var zip_opt_len; + var zip_static_len; + var zip_deflate_data; + var zip_deflate_pos; + + /* objects (deflate) */ + + function zip_DeflateCT() { + this.fc = 0; // frequency count or bit string + this.dl = 0; // father node in Huffman tree or length of bit string + } + + function zip_DeflateTreeDesc() { + this.dyn_tree = null; // the dynamic tree + this.static_tree = null; // corresponding static tree or NULL + this.extra_bits = null; // extra bits for each code or NULL + this.extra_base = 0; // base index for extra_bits + this.elems = 0; // max number of elements in the tree + this.max_length = 0; // max bit length for the codes + this.max_code = 0; // largest code with non zero frequency + } + + /* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ + function zip_DeflateConfiguration(a, b, c, d) { + this.good_length = a; // reduce lazy search above this match length + this.max_lazy = b; // do not perform lazy search above this match length + this.nice_length = c; // quit search above this match length + this.max_chain = d; + } + + function zip_DeflateBuffer() { + this.next = null; + this.len = 0; + this.ptr = new Array(zip_OUTBUFSIZ); + this.off = 0; + } + + /* constant tables */ + var zip_extra_lbits = [ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0]; + var zip_extra_dbits = [ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13]; + var zip_extra_blbits = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7]; + var zip_bl_order = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; + var zip_configuration_table = [ + new zip_DeflateConfiguration(0, 0, 0, 0), + new zip_DeflateConfiguration(4, 4, 8, 4), + new zip_DeflateConfiguration(4, 5, 16, 8), + new zip_DeflateConfiguration(4, 6, 32, 32), + new zip_DeflateConfiguration(4, 4, 16, 16), + new zip_DeflateConfiguration(8, 16, 32, 32), + new zip_DeflateConfiguration(8, 16, 128, 128), + new zip_DeflateConfiguration(8, 32, 128, 256), + new zip_DeflateConfiguration(32, 128, 258, 1024), + new zip_DeflateConfiguration(32, 258, 258, 4096)]; + + + /* routines (deflate) */ + + function zip_deflate_start(level) { + var i; + + if (!level) + level = zip_DEFAULT_LEVEL; + else if (level < 1) + level = 1; + else if (level > 9) + level = 9; + + zip_compr_level = level; + zip_initflag = false; + zip_eofile = false; + if (zip_outbuf != null) + return; + + zip_free_queue = zip_qhead = zip_qtail = null; + zip_outbuf = new Array(zip_OUTBUFSIZ); + zip_window = new Array(zip_window_size); + zip_d_buf = new Array(zip_DIST_BUFSIZE); + zip_l_buf = new Array(zip_INBUFSIZ + zip_INBUF_EXTRA); + zip_prev = new Array(1 << zip_BITS); + zip_dyn_ltree = new Array(zip_HEAP_SIZE); + for (i = 0; i < zip_HEAP_SIZE; i++) + zip_dyn_ltree[i] = new zip_DeflateCT(); + zip_dyn_dtree = new Array(2 * zip_D_CODES + 1); + for (i = 0; i < 2 * zip_D_CODES + 1; i++) + zip_dyn_dtree[i] = new zip_DeflateCT(); + zip_static_ltree = new Array(zip_L_CODES + 2); + for (i = 0; i < zip_L_CODES + 2; i++) + zip_static_ltree[i] = new zip_DeflateCT(); + zip_static_dtree = new Array(zip_D_CODES); + for (i = 0; i < zip_D_CODES; i++) + zip_static_dtree[i] = new zip_DeflateCT(); + zip_bl_tree = new Array(2 * zip_BL_CODES + 1); + for (i = 0; i < 2 * zip_BL_CODES + 1; i++) + zip_bl_tree[i] = new zip_DeflateCT(); + zip_l_desc = new zip_DeflateTreeDesc(); + zip_d_desc = new zip_DeflateTreeDesc(); + zip_bl_desc = new zip_DeflateTreeDesc(); + zip_bl_count = new Array(zip_MAX_BITS + 1); + zip_heap = new Array(2 * zip_L_CODES + 1); + zip_depth = new Array(2 * zip_L_CODES + 1); + zip_length_code = new Array(zip_MAX_MATCH - zip_MIN_MATCH + 1); + zip_dist_code = new Array(512); + zip_base_length = new Array(zip_LENGTH_CODES); + zip_base_dist = new Array(zip_D_CODES); + zip_flag_buf = new Array(parseInt(zip_LIT_BUFSIZE / 8)); + } + + function zip_deflate_end() { + zip_free_queue = zip_qhead = zip_qtail = null; + zip_outbuf = null; + zip_window = null; + zip_d_buf = null; + zip_l_buf = null; + zip_prev = null; + zip_dyn_ltree = null; + zip_dyn_dtree = null; + zip_static_ltree = null; + zip_static_dtree = null; + zip_bl_tree = null; + zip_l_desc = null; + zip_d_desc = null; + zip_bl_desc = null; + zip_bl_count = null; + zip_heap = null; + zip_depth = null; + zip_length_code = null; + zip_dist_code = null; + zip_base_length = null; + zip_base_dist = null; + zip_flag_buf = null; + } + + function zip_reuse_queue(p) { + p.next = zip_free_queue; + zip_free_queue = p; + } + + function zip_new_queue() { + var p; + + if (zip_free_queue != null) { + p = zip_free_queue; + zip_free_queue = zip_free_queue.next; + } + else + p = new zip_DeflateBuffer(); + p.next = null; + p.len = p.off = 0; + + return p; + } + + function zip_head1(i) { + return zip_prev[zip_WSIZE + i]; + } + + function zip_head2(i, val) { + return zip_prev[zip_WSIZE + i] = val; + } + + /* put_byte is used for the compressed output, put_ubyte for the + * uncompressed output. However unlzw() uses window for its + * suffix table instead of its output buffer, so it does not use put_ubyte + * (to be cleaned up). + */ + function zip_put_byte(c) { + zip_outbuf[zip_outoff + zip_outcnt++] = c; + if (zip_outoff + zip_outcnt == zip_OUTBUFSIZ) + zip_qoutbuf(); + } + + /* Output a 16 bit value, lsb first */ + function zip_put_short(w) { + w &= 0xffff; + if (zip_outoff + zip_outcnt < zip_OUTBUFSIZ - 2) { + zip_outbuf[zip_outoff + zip_outcnt++] = (w & 0xff); + zip_outbuf[zip_outoff + zip_outcnt++] = (w >>> 8); + } else { + zip_put_byte(w & 0xff); + zip_put_byte(w >>> 8); + } + } + + /* ========================================================================== + * Insert string s in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of s are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ + function zip_INSERT_STRING() { + zip_ins_h = ((zip_ins_h << zip_H_SHIFT) + ^ (zip_window[zip_strstart + zip_MIN_MATCH - 1] & 0xff)) + & zip_HASH_MASK; + zip_hash_head = zip_head1(zip_ins_h); + zip_prev[zip_strstart & zip_WMASK] = zip_hash_head; + zip_head2(zip_ins_h, zip_strstart); + } + + /* Send a code of the given tree. c and tree must not have side effects */ + function zip_SEND_CODE(c, tree) { + zip_send_bits(tree[c].fc, tree[c].dl); + } + + /* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. dist_code[256] and dist_code[257] are never + * used. + */ + function zip_D_CODE(dist) { + return (dist < 256 ? zip_dist_code[dist] + : zip_dist_code[256 + (dist >> 7)]) & 0xff; + } + + /* ========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ + function zip_SMALLER(tree, n, m) { + return tree[n].fc < tree[m].fc || + (tree[n].fc == tree[m].fc && zip_depth[n] <= zip_depth[m]); + } + + /* ========================================================================== + * read string data + */ + function zip_read_buff(buff, offset, n) { + var i; + for (i = 0; i < n && zip_deflate_pos < zip_deflate_data.length; i++) + buff[offset + i] = + zip_deflate_data.charCodeAt(zip_deflate_pos++) & 0xff; + return i; + } + + /* ========================================================================== + * Initialize the "longest match" routines for a new file + */ + function zip_lm_init() { + var j; + + /* Initialize the hash table. */ + for (j = 0; j < zip_HASH_SIZE; j++) + // zip_head2(j, zip_NIL); + zip_prev[zip_WSIZE + j] = 0; + /* prev will be initialized on the fly */ + + /* Set the default configuration parameters: + */ + zip_max_lazy_match = zip_configuration_table[zip_compr_level].max_lazy; + zip_good_match = zip_configuration_table[zip_compr_level].good_length; + if (!zip_FULL_SEARCH) + zip_nice_match = zip_configuration_table[zip_compr_level].nice_length; + zip_max_chain_length = zip_configuration_table[zip_compr_level].max_chain; + + zip_strstart = 0; + zip_block_start = 0; + + zip_lookahead = zip_read_buff(zip_window, 0, 2 * zip_WSIZE); + if (zip_lookahead <= 0) { + zip_eofile = true; + zip_lookahead = 0; + return; + } + zip_eofile = false; + /* Make sure that we always have enough lookahead. This is important + * if input comes from a device such as a tty. + */ + while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) + zip_fill_window(); + + /* If lookahead < MIN_MATCH, ins_h is garbage, but this is + * not important since only literal bytes will be emitted. + */ + zip_ins_h = 0; + for (j = 0; j < zip_MIN_MATCH - 1; j++) { + // UPDATE_HASH(ins_h, window[j]); + zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[j] & 0xff)) & zip_HASH_MASK; + } + } + + /* ========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + */ + function zip_longest_match(cur_match) { + var chain_length = zip_max_chain_length; // max hash chain length + var scanp = zip_strstart; // current string + var matchp; // matched string + var len; // length of current match + var best_len = zip_prev_length; // best match length so far + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + var limit = (zip_strstart > zip_MAX_DIST ? zip_strstart - zip_MAX_DIST : zip_NIL); + + var strendp = zip_strstart + zip_MAX_MATCH; + var scan_end1 = zip_window[scanp + best_len - 1]; + var scan_end = zip_window[scanp + best_len]; + + /* Do not waste too much time if we already have a good match: */ + if (zip_prev_length >= zip_good_match) + chain_length >>= 2; + + // Assert(encoder->strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead"); + + do { + // Assert(cur_match < encoder->strstart, "no future"); + matchp = cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ + if (zip_window[matchp + best_len] != scan_end || + zip_window[matchp + best_len - 1] != scan_end1 || + zip_window[matchp] != zip_window[scanp] || + zip_window[++matchp] != zip_window[scanp + 1]) { + continue; + } + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scanp += 2; + matchp++; + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + zip_window[++scanp] == zip_window[++matchp] && + scanp < strendp); + + len = zip_MAX_MATCH - (strendp - scanp); + scanp = strendp - zip_MAX_MATCH; + + if (len > best_len) { + zip_match_start = cur_match; + best_len = len; + if (zip_FULL_SEARCH) { + if (len >= zip_MAX_MATCH) break; + } else { + if (len >= zip_nice_match) break; + } + + scan_end1 = zip_window[scanp + best_len - 1]; + scan_end = zip_window[scanp + best_len]; + } + } while ((cur_match = zip_prev[cur_match & zip_WMASK]) > limit + && --chain_length != 0); + + return best_len; + } + + /* ========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead, and sets eofile if end of input file. + * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 + * OUT assertions: at least one byte has been read, or eofile is set; + * file reads are performed for at least two bytes (required for the + * translate_eol option). + */ + function zip_fill_window() { + var n, m; + + // Amount of free space at the end of the window. + var more = zip_window_size - zip_lookahead - zip_strstart; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (more == -1) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + } else if (zip_strstart >= zip_WSIZE + zip_MAX_DIST) { + /* By the IN assertion, the window is not empty so we can't confuse + * more == 0 with more == 64K on a 16 bit machine. + */ + // Assert(window_size == (ulg)2*WSIZE, "no sliding with BIG_MEM"); + + // System.arraycopy(window, WSIZE, window, 0, WSIZE); + for (n = 0; n < zip_WSIZE; n++) + zip_window[n] = zip_window[n + zip_WSIZE]; + + zip_match_start -= zip_WSIZE; + zip_strstart -= zip_WSIZE; /* we now have strstart >= MAX_DIST: */ + zip_block_start -= zip_WSIZE; + + for (n = 0; n < zip_HASH_SIZE; n++) { + m = zip_head1(n); + zip_head2(n, m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL); + } + for (n = 0; n < zip_WSIZE; n++) { + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + m = zip_prev[n]; + zip_prev[n] = (m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL); + } + more += zip_WSIZE; + } + // At this point, more >= 2 + if (!zip_eofile) { + n = zip_read_buff(zip_window, zip_strstart + zip_lookahead, more); + if (n <= 0) + zip_eofile = true; + else + zip_lookahead += n; + } + } + + /* ========================================================================== + * Processes a new input file and return its compressed length. This + * function does not perform lazy evaluationof matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ + function zip_deflate_fast() { + while (zip_lookahead != 0 && zip_qhead == null) { + var flush; // set if current block must be flushed + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + zip_INSERT_STRING(); + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (zip_hash_head != zip_NIL && + zip_strstart - zip_hash_head <= zip_MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + zip_match_length = zip_longest_match(zip_hash_head); + /* longest_match() sets match_start */ + if (zip_match_length > zip_lookahead) + zip_match_length = zip_lookahead; + } + if (zip_match_length >= zip_MIN_MATCH) { + // check_match(strstart, match_start, match_length); + + flush = zip_ct_tally(zip_strstart - zip_match_start, + zip_match_length - zip_MIN_MATCH); + zip_lookahead -= zip_match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (zip_match_length <= zip_max_lazy_match) { + zip_match_length--; // string at strstart already in hash table + do { + zip_strstart++; + zip_INSERT_STRING(); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH + * these bytes are garbage, but it does not matter since + * the next lookahead bytes will be emitted as literals. + */ + } while (--zip_match_length != 0); + zip_strstart++; + } else { + zip_strstart += zip_match_length; + zip_match_length = 0; + zip_ins_h = zip_window[zip_strstart] & 0xff; + // UPDATE_HASH(ins_h, window[strstart + 1]); + zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[zip_strstart + 1] & 0xff)) & zip_HASH_MASK; + + //#if MIN_MATCH != 3 + // Call UPDATE_HASH() MIN_MATCH-3 more times + //#endif + + } + } else { + /* No match, output a literal byte */ + flush = zip_ct_tally(0, zip_window[zip_strstart] & 0xff); + zip_lookahead--; + zip_strstart++; + } + if (flush) { + zip_flush_block(0); + zip_block_start = zip_strstart; + } + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) + zip_fill_window(); + } + } + + function zip_deflate_better() { + /* Process the input block. */ + while (zip_lookahead != 0 && zip_qhead == null) { + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + zip_INSERT_STRING(); + + /* Find the longest match, discarding those <= prev_length. + */ + zip_prev_length = zip_match_length; + zip_prev_match = zip_match_start; + zip_match_length = zip_MIN_MATCH - 1; + + if (zip_hash_head != zip_NIL && + zip_prev_length < zip_max_lazy_match && + zip_strstart - zip_hash_head <= zip_MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + zip_match_length = zip_longest_match(zip_hash_head); + /* longest_match() sets match_start */ + if (zip_match_length > zip_lookahead) + zip_match_length = zip_lookahead; + + /* Ignore a length 3 match if it is too distant: */ + if (zip_match_length == zip_MIN_MATCH && + zip_strstart - zip_match_start > zip_TOO_FAR) { + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + zip_match_length--; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (zip_prev_length >= zip_MIN_MATCH && + zip_match_length <= zip_prev_length) { + var flush; // set if current block must be flushed + + // check_match(strstart - 1, prev_match, prev_length); + flush = zip_ct_tally(zip_strstart - 1 - zip_prev_match, + zip_prev_length - zip_MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. + */ + zip_lookahead -= zip_prev_length - 1; + zip_prev_length -= 2; + do { + zip_strstart++; + zip_INSERT_STRING(); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH + * these bytes are garbage, but it does not matter since the + * next lookahead bytes will always be emitted as literals. + */ + } while (--zip_prev_length != 0); + zip_match_available = 0; + zip_match_length = zip_MIN_MATCH - 1; + zip_strstart++; + if (flush) { + zip_flush_block(0); + zip_block_start = zip_strstart; + } + } else if (zip_match_available != 0) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + if (zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff)) { + zip_flush_block(0); + zip_block_start = zip_strstart; + } + zip_strstart++; + zip_lookahead--; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + zip_match_available = 1; + zip_strstart++; + zip_lookahead--; + } + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) + zip_fill_window(); + } + } + + function zip_init_deflate() { + if (zip_eofile) + return; + zip_bi_buf = 0; + zip_bi_valid = 0; + zip_ct_init(); + zip_lm_init(); + + zip_qhead = null; + zip_outcnt = 0; + zip_outoff = 0; + + if (zip_compr_level <= 3) { + zip_prev_length = zip_MIN_MATCH - 1; + zip_match_length = 0; + } + else { + zip_match_length = zip_MIN_MATCH - 1; + zip_match_available = 0; + } + + zip_complete = false; + } + + /* ========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ + function zip_deflate_internal(buff, off, buff_size) { + var n; + + if (!zip_initflag) { + zip_init_deflate(); + zip_initflag = true; + if (zip_lookahead == 0) { // empty + zip_complete = true; + return 0; + } + } + + if ((n = zip_qcopy(buff, off, buff_size)) == buff_size) + return buff_size; + + if (zip_complete) + return n; + + if (zip_compr_level <= 3) // optimized for speed + zip_deflate_fast(); + else + zip_deflate_better(); + if (zip_lookahead == 0) { + if (zip_match_available != 0) + zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff); + zip_flush_block(1); + zip_complete = true; + } + return n + zip_qcopy(buff, n + off, buff_size - n); + } + + function zip_qcopy(buff, off, buff_size) { + var n, i, j; + + n = 0; + while (zip_qhead != null && n < buff_size) { + i = buff_size - n; + if (i > zip_qhead.len) + i = zip_qhead.len; + // System.arraycopy(qhead.ptr, qhead.off, buff, off + n, i); + for (j = 0; j < i; j++) + buff[off + n + j] = zip_qhead.ptr[zip_qhead.off + j]; + + zip_qhead.off += i; + zip_qhead.len -= i; + n += i; + if (zip_qhead.len == 0) { + var p; + p = zip_qhead; + zip_qhead = zip_qhead.next; + zip_reuse_queue(p); + } + } + + if (n == buff_size) + return n; + + if (zip_outoff < zip_outcnt) { + i = buff_size - n; + if (i > zip_outcnt - zip_outoff) + i = zip_outcnt - zip_outoff; + // System.arraycopy(outbuf, outoff, buff, off + n, i); + for (j = 0; j < i; j++) + buff[off + n + j] = zip_outbuf[zip_outoff + j]; + zip_outoff += i; + n += i; + if (zip_outcnt == zip_outoff) + zip_outcnt = zip_outoff = 0; + } + return n; + } + + /* ========================================================================== + * Allocate the match buffer, initialize the various tables and save the + * location of the internal file attribute (ascii/binary) and method + * (DEFLATE/STORE). + */ + function zip_ct_init() { + var n; // iterates over tree elements + var bits; // bit counter + var length; // length value + var code; // code value + var dist; // distance index + + if (zip_static_dtree[0].dl != 0) return; // ct_init already called + + zip_l_desc.dyn_tree = zip_dyn_ltree; + zip_l_desc.static_tree = zip_static_ltree; + zip_l_desc.extra_bits = zip_extra_lbits; + zip_l_desc.extra_base = zip_LITERALS + 1; + zip_l_desc.elems = zip_L_CODES; + zip_l_desc.max_length = zip_MAX_BITS; + zip_l_desc.max_code = 0; + + zip_d_desc.dyn_tree = zip_dyn_dtree; + zip_d_desc.static_tree = zip_static_dtree; + zip_d_desc.extra_bits = zip_extra_dbits; + zip_d_desc.extra_base = 0; + zip_d_desc.elems = zip_D_CODES; + zip_d_desc.max_length = zip_MAX_BITS; + zip_d_desc.max_code = 0; + + zip_bl_desc.dyn_tree = zip_bl_tree; + zip_bl_desc.static_tree = null; + zip_bl_desc.extra_bits = zip_extra_blbits; + zip_bl_desc.extra_base = 0; + zip_bl_desc.elems = zip_BL_CODES; + zip_bl_desc.max_length = zip_MAX_BL_BITS; + zip_bl_desc.max_code = 0; + + // Initialize the mapping length (0..255) -> length code (0..28) + length = 0; + for (code = 0; code < zip_LENGTH_CODES - 1; code++) { + zip_base_length[code] = length; + for (n = 0; n < (1 << zip_extra_lbits[code]); n++) + zip_length_code[length++] = code; + } + // Assert (length == 256, "ct_init: length != 256"); + + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + zip_length_code[length - 1] = code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0; code < 16; code++) { + zip_base_dist[code] = dist; + for (n = 0; n < (1 << zip_extra_dbits[code]); n++) { + zip_dist_code[dist++] = code; + } + } + // Assert (dist == 256, "ct_init: dist != 256"); + dist >>= 7; // from now on, all distances are divided by 128 + for (; code < zip_D_CODES; code++) { + zip_base_dist[code] = dist << 7; + for (n = 0; n < (1 << (zip_extra_dbits[code] - 7)); n++) + zip_dist_code[256 + dist++] = code; + } + // Assert (dist == 256, "ct_init: 256+dist != 512"); + + // Construct the codes of the static literal tree + for (bits = 0; bits <= zip_MAX_BITS; bits++) + zip_bl_count[bits] = 0; + n = 0; + while (n <= 143) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; } + while (n <= 255) { zip_static_ltree[n++].dl = 9; zip_bl_count[9]++; } + while (n <= 279) { zip_static_ltree[n++].dl = 7; zip_bl_count[7]++; } + while (n <= 287) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; } + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + zip_gen_codes(zip_static_ltree, zip_L_CODES + 1); + + /* The static distance tree is trivial: */ + for (n = 0; n < zip_D_CODES; n++) { + zip_static_dtree[n].dl = 5; + zip_static_dtree[n].fc = zip_bi_reverse(n, 5); + } + + // Initialize the first block of the first file: + zip_init_block(); + } + + /* ========================================================================== + * Initialize a new block. + */ + function zip_init_block() { + var n; // iterates over tree elements + + // Initialize the trees. + for (n = 0; n < zip_L_CODES; n++) zip_dyn_ltree[n].fc = 0; + for (n = 0; n < zip_D_CODES; n++) zip_dyn_dtree[n].fc = 0; + for (n = 0; n < zip_BL_CODES; n++) zip_bl_tree[n].fc = 0; + + zip_dyn_ltree[zip_END_BLOCK].fc = 1; + zip_opt_len = zip_static_len = 0; + zip_last_lit = zip_last_dist = zip_last_flags = 0; + zip_flags = 0; + zip_flag_bit = 1; + } + + /* ========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ + function zip_pqdownheap( + tree, // the tree to restore + k) { // node to move down + var v = zip_heap[k]; + var j = k << 1; // left son of k + + while (j <= zip_heap_len) { + // Set j to the smallest of the two sons: + if (j < zip_heap_len && + zip_SMALLER(tree, zip_heap[j + 1], zip_heap[j])) + j++; + + // Exit if v is smaller than both sons + if (zip_SMALLER(tree, v, zip_heap[j])) + break; + + // Exchange v with the smallest son + zip_heap[k] = zip_heap[j]; + k = j; + + // And continue down the tree, setting j to the left son of k + j <<= 1; + } + zip_heap[k] = v; + } + + /* ========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ + function zip_gen_bitlen(desc) { // the tree descriptor + var tree = desc.dyn_tree; + var extra = desc.extra_bits; + var base = desc.extra_base; + var max_code = desc.max_code; + var max_length = desc.max_length; + var stree = desc.static_tree; + var h; // heap index + var n, m; // iterate over the tree elements + var bits; // bit length + var xbits; // extra bits + var f; // frequency + var overflow = 0; // number of elements with bit length too large + + for (bits = 0; bits <= zip_MAX_BITS; bits++) + zip_bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[zip_heap[zip_heap_max]].dl = 0; // root of the heap + + for (h = zip_heap_max + 1; h < zip_HEAP_SIZE; h++) { + n = zip_heap[h]; + bits = tree[tree[n].dl].dl + 1; + if (bits > max_length) { + bits = max_length; + overflow++; + } + tree[n].dl = bits; + // We overwrite tree[n].dl which is no longer needed + + if (n > max_code) + continue; // not a leaf node + + zip_bl_count[bits]++; + xbits = 0; + if (n >= base) + xbits = extra[n - base]; + f = tree[n].fc; + zip_opt_len += f * (bits + xbits); + if (stree != null) + zip_static_len += f * (stree[n].dl + xbits); + } + if (overflow == 0) + return; + + // This happens for example on obj2 and pic of the Calgary corpus + + // Find the first bit length which could increase: + do { + bits = max_length - 1; + while (zip_bl_count[bits] == 0) + bits--; + zip_bl_count[bits]--; // move one leaf down the tree + zip_bl_count[bits + 1] += 2; // move one overflow item as its brother + zip_bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = zip_bl_count[bits]; + while (n != 0) { + m = zip_heap[--h]; + if (m > max_code) + continue; + if (tree[m].dl != bits) { + zip_opt_len += (bits - tree[m].dl) * tree[m].fc; + tree[m].fc = bits; + } + n--; + } + } + } + + /* ========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ + function zip_gen_codes(tree, // the tree to decorate + max_code) { // largest code with non zero frequency + var next_code = new Array(zip_MAX_BITS + 1); // next code value for each bit length + var code = 0; // running code value + var bits; // bit index + var n; // code index + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= zip_MAX_BITS; bits++) { + code = ((code + zip_bl_count[bits - 1]) << 1); + next_code[bits] = code; + } + + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + // Assert (code + encoder->bl_count[MAX_BITS]-1 == (1<> 1; n >= 1; n--) + zip_pqdownheap(tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + do { + n = zip_heap[zip_SMALLEST]; + zip_heap[zip_SMALLEST] = zip_heap[zip_heap_len--]; + zip_pqdownheap(tree, zip_SMALLEST); + + m = zip_heap[zip_SMALLEST]; // m = node of next least frequency + + // keep the nodes sorted by frequency + zip_heap[--zip_heap_max] = n; + zip_heap[--zip_heap_max] = m; + + // Create a new node father of n and m + tree[node].fc = tree[n].fc + tree[m].fc; + // depth[node] = (char)(MAX(depth[n], depth[m]) + 1); + if (zip_depth[n] > zip_depth[m] + 1) + zip_depth[node] = zip_depth[n]; + else + zip_depth[node] = zip_depth[m] + 1; + tree[n].dl = tree[m].dl = node; + + // and insert the new node in the heap + zip_heap[zip_SMALLEST] = node++; + zip_pqdownheap(tree, zip_SMALLEST); + + } while (zip_heap_len >= 2); + + zip_heap[--zip_heap_max] = zip_heap[zip_SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + zip_gen_bitlen(desc); + + // The field len is now set, we can generate the bit codes + zip_gen_codes(tree, max_code); + } + + /* ========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. Updates opt_len to take into account the repeat + * counts. (The contribution of the bit length codes will be added later + * during the construction of bl_tree.) + */ + function zip_scan_tree(tree,// the tree to be scanned + max_code) { // and its largest code of non zero frequency + var n; // iterates over all tree elements + var prevlen = -1; // last emitted length + var curlen; // length of current code + var nextlen = tree[0].dl; // length of next code + var count = 0; // repeat count of the current code + var max_count = 7; // max repeat count + var min_count = 4; // min repeat count + + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } + tree[max_code + 1].dl = 0xffff; // guard + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n + 1].dl; + if (++count < max_count && curlen == nextlen) + continue; + else if (count < min_count) + zip_bl_tree[curlen].fc += count; + else if (curlen != 0) { + if (curlen != prevlen) + zip_bl_tree[curlen].fc++; + zip_bl_tree[zip_REP_3_6].fc++; + } else if (count <= 10) + zip_bl_tree[zip_REPZ_3_10].fc++; + else + zip_bl_tree[zip_REPZ_11_138].fc++; + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } else if (curlen == nextlen) { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } + } + + /* ========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ + function zip_send_tree(tree, // the tree to be scanned + max_code) { // and its largest code of non zero frequency + var n; // iterates over all tree elements + var prevlen = -1; // last emitted length + var curlen; // length of current code + var nextlen = tree[0].dl; // length of next code + var count = 0; // repeat count of the current code + var max_count = 7; // max repeat count + var min_count = 4; // min repeat count + + /* tree[max_code+1].dl = -1; */ /* guard already set */ + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n + 1].dl; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { zip_SEND_CODE(curlen, zip_bl_tree); } while (--count != 0); + } else if (curlen != 0) { + if (curlen != prevlen) { + zip_SEND_CODE(curlen, zip_bl_tree); + count--; + } + // Assert(count >= 3 && count <= 6, " 3_6?"); + zip_SEND_CODE(zip_REP_3_6, zip_bl_tree); + zip_send_bits(count - 3, 2); + } else if (count <= 10) { + zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree); + zip_send_bits(count - 3, 3); + } else { + zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree); + zip_send_bits(count - 11, 7); + } + count = 0; + prevlen = curlen; + if (nextlen == 0) { + max_count = 138; + min_count = 3; + } else if (curlen == nextlen) { + max_count = 6; + min_count = 3; + } else { + max_count = 7; + min_count = 4; + } + } + } + + /* ========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ + function zip_build_bl_tree() { + var max_blindex; // index of last bit length code of non zero freq + + // Determine the bit length frequencies for literal and distance trees + zip_scan_tree(zip_dyn_ltree, zip_l_desc.max_code); + zip_scan_tree(zip_dyn_dtree, zip_d_desc.max_code); + + // Build the bit length tree: + zip_build_tree(zip_bl_desc); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = zip_BL_CODES - 1; max_blindex >= 3; max_blindex--) { + if (zip_bl_tree[zip_bl_order[max_blindex]].dl != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + zip_opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + // Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + // encoder->opt_len, encoder->static_len)); + + return max_blindex; + } + + /* ========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ + function zip_send_all_trees(lcodes, dcodes, blcodes) { // number of codes for each tree + var rank; // index in bl_order + + // Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + // Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + // "too many codes"); + // Tracev((stderr, "\nbl counts: ")); + zip_send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt + zip_send_bits(dcodes - 1, 5); + zip_send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt + for (rank = 0; rank < blcodes; rank++) { + // Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + zip_send_bits(zip_bl_tree[zip_bl_order[rank]].dl, 3); + } + + // send the literal tree + zip_send_tree(zip_dyn_ltree, lcodes - 1); + + // send the distance tree + zip_send_tree(zip_dyn_dtree, dcodes - 1); + } + + /* ========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ + function zip_flush_block(eof) { // true if this is the last block for a file + var opt_lenb, static_lenb; // opt_len and static_len in bytes + var max_blindex; // index of last bit length code of non zero freq + var stored_len; // length of input block + + stored_len = zip_strstart - zip_block_start; + zip_flag_buf[zip_last_flags] = zip_flags; // Save the flags for the last 8 items + + // Construct the literal and distance trees + zip_build_tree(zip_l_desc); + // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", + // encoder->opt_len, encoder->static_len)); + + zip_build_tree(zip_d_desc); + // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", + // encoder->opt_len, encoder->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = zip_build_bl_tree(); + + // Determine the best encoding. Compute first the block length in bytes + opt_lenb = (zip_opt_len + 3 + 7) >> 3; + static_lenb = (zip_static_len + 3 + 7) >> 3; + + // Trace((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", + // opt_lenb, encoder->opt_len, + // static_lenb, encoder->static_len, stored_len, + // encoder->last_lit, encoder->last_dist)); + + if (static_lenb <= opt_lenb) + opt_lenb = static_lenb; + if (stored_len + 4 <= opt_lenb // 4: two words for the lengths + && zip_block_start >= 0) { + var i; + + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + zip_send_bits((zip_STORED_BLOCK << 1) + eof, 3); /* send block type */ + zip_bi_windup(); /* align on byte boundary */ + zip_put_short(stored_len); + zip_put_short(~stored_len); + + // copy block + /* + p = &window[block_start]; + for(i = 0; i < stored_len; i++) + put_byte(p[i]); + */ + for (i = 0; i < stored_len; i++) + zip_put_byte(zip_window[zip_block_start + i]); + + } else if (static_lenb == opt_lenb) { + zip_send_bits((zip_STATIC_TREES << 1) + eof, 3); + zip_compress_block(zip_static_ltree, zip_static_dtree); + } else { + zip_send_bits((zip_DYN_TREES << 1) + eof, 3); + zip_send_all_trees(zip_l_desc.max_code + 1, + zip_d_desc.max_code + 1, + max_blindex + 1); + zip_compress_block(zip_dyn_ltree, zip_dyn_dtree); + } + + zip_init_block(); + + if (eof != 0) + zip_bi_windup(); + } + + /* ========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ + function zip_ct_tally( + dist, // distance of matched string + lc) { // match length-MIN_MATCH or unmatched char (if dist==0) + zip_l_buf[zip_last_lit++] = lc; + if (dist == 0) { + // lc is the unmatched char + zip_dyn_ltree[lc].fc++; + } else { + // Here, lc is the match length - MIN_MATCH + dist--; // dist = match distance - 1 + // Assert((ush)dist < (ush)MAX_DIST && + // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + // (ush)D_CODE(dist) < (ush)D_CODES, "ct_tally: bad match"); + + zip_dyn_ltree[zip_length_code[lc] + zip_LITERALS + 1].fc++; + zip_dyn_dtree[zip_D_CODE(dist)].fc++; + + zip_d_buf[zip_last_dist++] = dist; + zip_flags |= zip_flag_bit; + } + zip_flag_bit <<= 1; + + // Output the flags if they fill a byte + if ((zip_last_lit & 7) == 0) { + zip_flag_buf[zip_last_flags++] = zip_flags; + zip_flags = 0; + zip_flag_bit = 1; + } + // Try to guess if it is profitable to stop the current block here + if (zip_compr_level > 2 && (zip_last_lit & 0xfff) == 0) { + // Compute an upper bound for the compressed length + var out_length = zip_last_lit * 8; + var in_length = zip_strstart - zip_block_start; + var dcode; + + for (dcode = 0; dcode < zip_D_CODES; dcode++) { + out_length += zip_dyn_dtree[dcode].fc * (5 + zip_extra_dbits[dcode]); + } + out_length >>= 3; + // Trace((stderr,"\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", + // encoder->last_lit, encoder->last_dist, in_length, out_length, + // 100L - out_length*100L/in_length)); + if (zip_last_dist < parseInt(zip_last_lit / 2) && + out_length < parseInt(in_length / 2)) + return true; + } + return (zip_last_lit == zip_LIT_BUFSIZE - 1 || + zip_last_dist == zip_DIST_BUFSIZE); + /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ + } + + /* ========================================================================== + * Send the block data compressed using the given Huffman trees + */ + function zip_compress_block( + ltree, // literal tree + dtree) { // distance tree + var dist; // distance of matched string + var lc; // match length or unmatched char (if dist == 0) + var lx = 0; // running index in l_buf + var dx = 0; // running index in d_buf + var fx = 0; // running index in flag_buf + var flag = 0; // current flags + var code; // the code to send + var extra; // number of extra bits to send + + if (zip_last_lit != 0) do { + if ((lx & 7) == 0) + flag = zip_flag_buf[fx++]; + lc = zip_l_buf[lx++] & 0xff; + if ((flag & 1) == 0) { + zip_SEND_CODE(lc, ltree); /* send a literal byte */ + // Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + // Here, lc is the match length - MIN_MATCH + code = zip_length_code[lc]; + zip_SEND_CODE(code + zip_LITERALS + 1, ltree); // send the length code + extra = zip_extra_lbits[code]; + if (extra != 0) { + lc -= zip_base_length[code]; + zip_send_bits(lc, extra); // send the extra length bits + } + dist = zip_d_buf[dx++]; + // Here, dist is the match distance - 1 + code = zip_D_CODE(dist); + // Assert (code < D_CODES, "bad d_code"); + + zip_SEND_CODE(code, dtree); // send the distance code + extra = zip_extra_dbits[code]; + if (extra != 0) { + dist -= zip_base_dist[code]; + zip_send_bits(dist, extra); // send the extra distance bits + } + } // literal or match pair ? + flag >>= 1; + } while (lx < zip_last_lit); + + zip_SEND_CODE(zip_END_BLOCK, ltree); + } + + /* ========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ + var zip_Buf_size = 16; // bit size of bi_buf + function zip_send_bits( + value, // value to send + length) { // number of bits + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (zip_bi_valid > zip_Buf_size - length) { + zip_bi_buf |= (value << zip_bi_valid); + zip_put_short(zip_bi_buf); + zip_bi_buf = (value >> (zip_Buf_size - zip_bi_valid)); + zip_bi_valid += length - zip_Buf_size; + } else { + zip_bi_buf |= value << zip_bi_valid; + zip_bi_valid += length; + } + } + + /* ========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ + function zip_bi_reverse( + code, // the value to invert + len) { // its bit length + var res = 0; + do { + res |= code & 1; + code >>= 1; + res <<= 1; + } while (--len > 0); + return res >> 1; + } + + /* ========================================================================== + * Write out any remaining bits in an incomplete byte. + */ + function zip_bi_windup() { + if (zip_bi_valid > 8) { + zip_put_short(zip_bi_buf); + } else if (zip_bi_valid > 0) { + zip_put_byte(zip_bi_buf); + } + zip_bi_buf = 0; + zip_bi_valid = 0; + } + + function zip_qoutbuf() { + if (zip_outcnt != 0) { + var q, i; + q = zip_new_queue(); + if (zip_qhead == null) + zip_qhead = zip_qtail = q; + else + zip_qtail = zip_qtail.next = q; + q.len = zip_outcnt - zip_outoff; + // System.arraycopy(zip_outbuf, zip_outoff, q.ptr, 0, q.len); + for (i = 0; i < q.len; i++) + q.ptr[i] = zip_outbuf[zip_outoff + i]; + zip_outcnt = zip_outoff = 0; + } + } + + return function deflate(str, level) { + var i, j; + + zip_deflate_data = str; + zip_deflate_pos = 0; + if (typeof level == "undefined") + level = zip_DEFAULT_LEVEL; + zip_deflate_start(level); + + var buff = new Array(1024); + var aout = []; + while ((i = zip_deflate_internal(buff, 0, buff.length)) > 0) { + var cbuf = new Array(i); + for (j = 0; j < i; j++) { + cbuf[j] = String.fromCharCode(buff[j]); + } + aout[aout.length] = cbuf.join(""); + } + zip_deflate_data = null; // G.C. + return aout.join(""); + }; +})(); \ No newline at end of file diff --git a/js/main.min.8ab8f81ff7e1454d30024cd6f956d4d341c3a97e2a673f988065f2ee4e147922.js b/js/main.min.8ab8f81ff7e1454d30024cd6f956d4d341c3a97e2a673f988065f2ee4e147922.js new file mode 100644 index 00000000..dcc5bae6 --- /dev/null +++ b/js/main.min.8ab8f81ff7e1454d30024cd6f956d4d341c3a97e2a673f988065f2ee4e147922.js @@ -0,0 +1 @@ +(function(a){'use strict';a(function(){a('[data-toggle="tooltip"]').tooltip(),a('[data-toggle="popover"]').popover(),a('.popover-dismiss').popover({trigger:'focus'})});function b(a){return a.offset().top+a.outerHeight()}a(function(){var c=a(".js-td-cover"),e,f,d;if(!c.length)return;e=b(c),f=a('.js-navbar-scroll').offset().top,d=Math.ceil(a('.js-navbar-scroll').outerHeight()),e-f',a.href='#'+b.id,b.insertAdjacentElement('beforeend',a),b.addEventListener('mouseenter',function(){a.style.visibility='initial'}),b.addEventListener('mouseleave',function(){a.style.visibility='hidden'})}})})}(jQuery),function(a){'use strict';a(document).ready(function(){const b=a('.td-search-input');b.data('html',!0),b.data('placement','bottom'),b.data('template',''),b.on('change',c=>{e(a(c.target)),b.blur()}),b.closest('form').on('submit',()=>!1);let c=null;const d=new Map;a.ajax(b.data('offline-search-index-json-src')).then(a=>{c=lunr(function(){this.ref('ref'),this.field('title',{boost:5}),this.field('categories',{boost:3}),this.field('tags',{boost:3}),this.field('description',{boost:2}),this.field('body'),a.forEach(a=>{this.add(a),d.set(a.ref,{title:a.title,excerpt:a.excerpt})})}),b.trigger('change')});const e=e=>{if(e.popover('dispose'),c===null)return;const f=e.val();if(f==='')return;const i=c.query(a=>{const b=lunr.tokenizer(f.toLowerCase());b.forEach(c=>{const b=c.toString();a.term(b,{boost:100}),a.term(b,{wildcard:lunr.Query.wildcard.LEADING|lunr.Query.wildcard.TRAILING,boost:10}),a.term(b,{editDistance:2})})}).slice(0,e.data('offline-search-max-results')),g=a('
');g.append(a('
').css({display:'flex',justifyContent:'space-between',marginBottom:'1em'}).append(a('').text('Search results').css({fontWeight:'bold'})).append(a('').addClass('fas fa-times search-result-close-button').css({cursor:'pointer'})));const h=a('
').css({maxHeight:`calc(100vh - ${e.offset().top-a(window).scrollTop()+180}px)`,overflowY:'auto'});g.append(h),i.length===0?h.append(a('

').text(`No results found for query "${f}"`)):i.forEach(e=>{const f=d.get(e.ref),g=b.data('offline-search-base-href')+e.ref.replace(/^\//,''),c=a('

').addClass('mt-4');c.append(a('').addClass('d-block text-muted').text(e.ref)),c.append(a('').addClass('d-block').css({fontSize:'1.2rem'}).attr('href',g).text(f.title)),c.append(a('

').text(f.excerpt)),h.append(c)}),e.on('shown.bs.popover',()=>{a('.search-result-close-button').on('click',()=>{e.val(''),e.trigger('change')})});const j=a.fn.tooltip.Constructor.Default.whiteList;j['*'].push('style'),e.data('content',g[0].outerHTML).popover({whiteList:j}).popover('show')}})}(jQuery),function(){var c=function(){a=document.createElement('div'),a.classList.add('drawioframe'),b=document.createElement('iframe'),a.appendChild(b),document.body.appendChild(a)},d=function(){a&&(document.body.removeChild(a),a=void 0,b=void 0)},e=function(a,g){var h="https://embed.diagrams.net/",e,f;h+='?embed=1&ui=atlas&spin=1&modified=unsavedChanges&proto=json&saveAndEdit=1&noSaveBtn=1',e=document.createElement('div'),e.classList.add('drawio'),a.parentNode.insertBefore(e,a),e.appendChild(a),f=document.createElement('button'),f.classList.add('drawiobtn'),f.insertAdjacentHTML('beforeend',''),e.appendChild(f),f.addEventListener('click',function(f){if(b)return;c();var e=function(f){var h=b.contentWindow,c,i;if(f.data.length>0&&f.source==h){if(c=JSON.parse(f.data),c.event=='init')h.postMessage(JSON.stringify({action:'load',xml:g}),'*');else if(c.event=='save')i=g.indexOf('data:image/png')==0?'xmlpng':'xmlsvg',h.postMessage(JSON.stringify({action:'export',format:i}),'*');else if(c.event=='export'){const d=a.src.replace(/^.*?([^/]+)$/,'$1'),b=document.createElement('a');b.setAttribute('href',c.data),b.setAttribute('download',d),document.body.appendChild(b),b.click(),b.parentNode.removeChild(b)}(c.event=='exit'||c.event=='export')&&(window.removeEventListener('message',e),d())}};window.addEventListener('message',e),b.setAttribute('src',h)})},b,a;document.addEventListener('DOMContentLoaded',function(){for(const d of document.getElementsByTagName('img')){const c=d,b=c.getAttribute('src');if(!b.endsWith('.svg')&&!b.endsWith('.png'))continue;const a=new XMLHttpRequest;a.responseType='blob',a.open("GET",b),a.addEventListener("load",function(){const b=new FileReader;b.addEventListener('load',function(){if(b.result.indexOf('mxfile')!=-1){const b=new FileReader;b.addEventListener('load',function(){const a=b.result;e(c,a)}),b.readAsDataURL(a.response)}}),b.readAsBinaryString(a.response)}),a.send()}})}() \ No newline at end of file diff --git a/js/prism.js b/js/prism.js new file mode 100644 index 00000000..ae881ac8 --- /dev/null +++ b/js/prism.js @@ -0,0 +1,21 @@ +/* PrismJS 1.21.0 +https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+bash+c+csharp+cpp+go+java+markdown+python+scss+sql+toml+yaml&plugins=toolbar+copy-to-clipboard */ +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,n=0,M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=l.reach);k+=y.value.length,y=y.next){var b=y.value;if(t.length>n.length)return;if(!(b instanceof W)){var x=1;if(h&&y!=t.tail.prev){m.lastIndex=k;var w=m.exec(n);if(!w)break;var A=w.index+(f&&w[1]?w[1].length:0),P=w.index+w[0].length,S=k;for(S+=y.value.length;S<=A;)y=y.next,S+=y.value.length;if(S-=y.value.length,k=S,y.value instanceof W)continue;for(var E=y;E!==t.tail&&(Sl.reach&&(l.reach=j);var C=y.prev;L&&(C=I(t,C,L),k+=L.length),z(t,C,x);var _=new W(o,g?M.tokenize(O,g):O,v,O);y=I(t,C,_),N&&I(t,y,N),1"+a.content+""},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),t=n.language,r=n.code,a=n.immediateClose;u.postMessage(M.highlight(r,M.languages[t],t)),a&&u.close()},!1)),M;var e=M.util.currentScript();function t(){M.manual||M.highlightAll()}if(e&&(M.filename=e.src,e.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var r=document.readyState;"loading"===r||"interactive"===r&&e&&e.defer?document.addEventListener("DOMContentLoaded",t):window.requestAnimationFrame?window.requestAnimationFrame(t):window.setTimeout(t,16)}return M}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); +Prism.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/,name:/[^\s<>'"]+/}},cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^$/i;var n={"included-cdata":{pattern://i,inside:s}};n["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var t={};t[a]={pattern:RegExp("(<__[^]*?>)(?:))*\\]\\]>|(?!)".replace(/__/g,function(){return a}),"i"),lookbehind:!0,greedy:!0,inside:n},Prism.languages.insertBefore("markup","cdata",t)}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml; +!function(e){var s=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+[\s\S]*?(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\((?!\s*\))\s*)(?:[^()]|\((?:[^()]|\([^()]*\))*\))+?(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+s.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+s.source+"$"),alias:"url"}}},selector:RegExp("[^{}\\s](?:[^{};\"']|"+s.source+")*?(?=\\s*\\{)"),string:{pattern:s,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var t=e.languages.markup;t&&(t.tag.addInlined("style","css"),e.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:t.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:e.languages.css}},alias:"language-css"}},t.tag))}(Prism); +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/}; +Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)(?:catch|finally)\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|(?:get|set)(?=\s*[\[$\w\xA0-\uFFFF])|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,function:/#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0},"function-variable":{pattern:/#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.js=Prism.languages.javascript; +!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|x[0-9a-fA-F]{1,2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)\w+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b\w+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+?)\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:n},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\](?:\\\\)*)(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\2)[^\\])*\2/,lookbehind:!0,greedy:!0,inside:n}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:n.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|aptitude|apt-cache|apt-get|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:if|then|else|elif|fi|for|while|in|case|esac|function|select|do|done|until)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|break|cd|continue|eval|exec|exit|export|getopts|hash|pwd|readonly|return|shift|test|times|trap|umask|unset|alias|bind|builtin|caller|command|declare|echo|enable|help|let|local|logout|mapfile|printf|read|readarray|source|type|typeset|ulimit|unalias|set|shopt)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:true|false)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|==?|!=?|=~|<<[<-]?|[&\d]?>>|\d?[<>]&?|&[>&]?|\|[&|]?|<=?|>=?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}};for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],r=n.variable[1].inside,s=0;s>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/,number:/(?:\b0x(?:[\da-f]+\.?[\da-f]*|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ful]*/i}),Prism.languages.insertBefore("c","string",{macro:{pattern:/(^\s*)#\s*[a-z]+(?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},Prism.languages.c.string],comment:Prism.languages.c.comment,directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:Prism.languages.c}}},constant:/\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/}),delete Prism.languages.c.boolean; +!function(s){function a(e,s){return e.replace(/<<(\d+)>>/g,function(e,n){return"(?:"+s[+n]+")"})}function t(e,n,s){return RegExp(a(e,n),s||"")}function e(e,n){for(var s=0;s>/g,function(){return"(?:"+e+")"});return e.replace(/<>/g,"[^\\s\\S]")}var n="bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",r="class enum interface struct",i="add alias and ascending async await by descending from get global group into join let nameof not notnull on or orderby partial remove select set unmanaged value when where where",o="abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield";function l(e){return"\\b(?:"+e.trim().replace(/ /g,"|")+")\\b"}var d=l(r),p=RegExp(l(n+" "+r+" "+i+" "+o)),c=l(r+" "+i+" "+o),u=l(n+" "+r+" "+o),g=e("<(?:[^<>;=+\\-*/%&|^]|<>)*>",2),b=e("\\((?:[^()]|<>)*\\)",2),h="@?\\b[A-Za-z_]\\w*\\b",f=a("<<0>>(?:\\s*<<1>>)?",[h,g]),m=a("(?!<<0>>)<<1>>(?:\\s*\\.\\s*<<1>>)*",[c,f]),k="\\[\\s*(?:,\\s*)*\\]",y=a("<<0>>(?:\\s*(?:\\?\\s*)?<<1>>)*(?:\\s*\\?)?",[m,k]),w=a("(?:<<0>>|<<1>>)(?:\\s*(?:\\?\\s*)?<<2>>)*(?:\\s*\\?)?",[a("\\(<<0>>+(?:,<<0>>+)+\\)",[a("[^,()<>[\\];=+\\-*/%&|^]|<<0>>|<<1>>|<<2>>",[g,b,k])]),m,k]),v={keyword:p,punctuation:/[<>()?,.:[\]]/},x="'(?:[^\r\n'\\\\]|\\\\.|\\\\[Uux][\\da-fA-F]{1,8})'",$='"(?:\\\\.|[^\\\\"\r\n])*"';s.languages.csharp=s.languages.extend("clike",{string:[{pattern:t("(^|[^$\\\\])<<0>>",['@"(?:""|\\\\[^]|[^\\\\"])*"(?!")']),lookbehind:!0,greedy:!0},{pattern:t("(^|[^@$\\\\])<<0>>",[$]),lookbehind:!0,greedy:!0},{pattern:RegExp(x),greedy:!0,alias:"character"}],"class-name":[{pattern:t("(\\busing\\s+static\\s+)<<0>>(?=\\s*;)",[m]),lookbehind:!0,inside:v},{pattern:t("(\\busing\\s+<<0>>\\s*=\\s*)<<1>>(?=\\s*;)",[h,w]),lookbehind:!0,inside:v},{pattern:t("(\\busing\\s+)<<0>>(?=\\s*=)",[h]),lookbehind:!0},{pattern:t("(\\b<<0>>\\s+)<<1>>",[d,f]),lookbehind:!0,inside:v},{pattern:t("(\\bcatch\\s*\\(\\s*)<<0>>",[m]),lookbehind:!0,inside:v},{pattern:t("(\\bwhere\\s+)<<0>>",[h]),lookbehind:!0},{pattern:t("(\\b(?:is(?:\\s+not)?|as)\\s+)<<0>>",[y]),lookbehind:!0,inside:v},{pattern:t("\\b<<0>>(?=\\s+(?!<<1>>)<<2>>(?:\\s*[=,;:{)\\]]|\\s+(?:in|when)\\b))",[w,u,h]),inside:v}],keyword:p,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:ul|lu|[dflmu])?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),s.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),s.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:t("([(,]\\s*)<<0>>(?=\\s*:)",[h]),lookbehind:!0,alias:"punctuation"}}),s.languages.insertBefore("csharp","class-name",{namespace:{pattern:t("(\\b(?:namespace|using)\\s+)<<0>>(?:\\s*\\.\\s*<<0>>)*(?=\\s*[;{])",[h]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:t("(\\b(?:default|typeof|sizeof)\\s*\\(\\s*)(?:[^()\\s]|\\s(?!\\s*\\))|<<0>>)*(?=\\s*\\))",[b]),lookbehind:!0,alias:"class-name",inside:v},"return-type":{pattern:t("<<0>>(?=\\s+(?:<<1>>\\s*(?:=>|[({]|\\.\\s*this\\s*\\[)|this\\s*\\[))",[w,m]),inside:v,alias:"class-name"},"constructor-invocation":{pattern:t("(\\bnew\\s+)<<0>>(?=\\s*[[({])",[w]),lookbehind:!0,inside:v,alias:"class-name"},"generic-method":{pattern:t("<<0>>\\s*<<1>>(?=\\s*\\()",[h,g]),inside:{function:t("^<<0>>",[h]),generic:{pattern:RegExp(g),alias:"class-name",inside:v}}},"type-list":{pattern:t("\\b((?:<<0>>\\s+<<1>>|where\\s+<<2>>)\\s*:\\s*)(?:<<3>>|<<4>>)(?:\\s*,\\s*(?:<<3>>|<<4>>))*(?=\\s*(?:where|[{;]|=>|$))",[d,f,h,w,p.source]),lookbehind:!0,inside:{keyword:p,"class-name":{pattern:RegExp(w),greedy:!0,inside:v},punctuation:/,/}},preprocessor:{pattern:/(^\s*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(\s*#)\b(?:define|elif|else|endif|endregion|error|if|line|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var _=$+"|"+x,B=a("/(?![*/])|//[^\r\n]*[\r\n]|/\\*(?:[^*]|\\*(?!/))*\\*/|<<0>>",[_]),E=e(a("[^\"'/()]|<<0>>|\\(<>*\\)",[B]),2),R="\\b(?:assembly|event|field|method|module|param|property|return|type)\\b",P=a("<<0>>(?:\\s*\\(<<1>>*\\))?",[m,E]);s.languages.insertBefore("csharp","class-name",{attribute:{pattern:t("((?:^|[^\\s\\w>)?])\\s*\\[\\s*)(?:<<0>>\\s*:\\s*)?<<1>>(?:\\s*,\\s*<<1>>)*(?=\\s*\\])",[R,P]),lookbehind:!0,greedy:!0,inside:{target:{pattern:t("^<<0>>(?=\\s*:)",[R]),alias:"keyword"},"attribute-arguments":{pattern:t("\\(<<0>>*\\)",[E]),inside:s.languages.csharp},"class-name":{pattern:RegExp(m),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var z=":[^}\r\n]+",S=e(a("[^\"'/()]|<<0>>|\\(<>*\\)",[B]),2),j=a("\\{(?!\\{)(?:(?![}:])<<0>>)*<<1>>?\\}",[S,z]),A=e(a("[^\"'/()]|/(?!\\*)|/\\*(?:[^*]|\\*(?!/))*\\*/|<<0>>|\\(<>*\\)",[_]),2),F=a("\\{(?!\\{)(?:(?![}:])<<0>>)*<<1>>?\\}",[A,z]);function U(e,n){return{interpolation:{pattern:t("((?:^|[^{])(?:\\{\\{)*)<<0>>",[e]),lookbehind:!0,inside:{"format-string":{pattern:t("(^\\{(?:(?![}:])<<0>>)*)<<1>>(?=\\}$)",[n,z]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:s.languages.csharp}}},string:/[\s\S]+/}}s.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:t('(^|[^\\\\])(?:\\$@|@\\$)"(?:""|\\\\[^]|\\{\\{|<<0>>|[^\\\\{"])*"',[j]),lookbehind:!0,greedy:!0,inside:U(j,S)},{pattern:t('(^|[^@\\\\])\\$"(?:\\\\.|\\{\\{|<<0>>|[^\\\\"{])*"',[F]),lookbehind:!0,greedy:!0,inside:U(F,A)}]})}(Prism),Prism.languages.dotnet=Prism.languages.cs=Prism.languages.csharp; +!function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|constinit|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/;e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp("(\\b(?:class|concept|enum|struct|typename)\\s+)(?!)\\w+".replace(//g,function(){return t.source})),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+\.?[\da-f']*|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+\.?[\d']*|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]*/i,greedy:!0},operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:true|false)\b/}),e.languages.insertBefore("cpp","string",{"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)(?:[^;{}"'])+?(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","operator",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(Prism); +Prism.languages.go=Prism.languages.extend("clike",{keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,builtin:/\b(?:bool|byte|complex(?:64|128)|error|float(?:32|64)|rune|string|u?int(?:8|16|32|64)?|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(?:ln)?|real|recover)\b/,boolean:/\b(?:_|iota|nil|true|false)\b/,operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,number:/(?:\b0x[a-f\d]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[-+]?\d+)?)i?/i,string:{pattern:/(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/,greedy:!0}}),delete Prism.languages.go["class-name"]; +!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|null|open|opens|package|private|protected|provides|public|record|requires|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,a=/\b[A-Z](?:\w*[a-z]\w*)?\b/;e.languages.java=e.languages.extend("clike",{"class-name":[a,/\b[A-Z]\w*(?=\s+\w+\s*[;,=())])/],keyword:t,function:[e.languages.clike.function,{pattern:/(\:\:)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x[\da-f_]*\.?[\da-f_p+-]+\b|(?:\b\d[\d_]*\.?[\d_]*|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0}}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"}}),e.languages.insertBefore("java","class-name",{annotation:{alias:"punctuation",pattern:/(^|[^.])@\w+/,lookbehind:!0},namespace:{pattern:RegExp("(\\b(?:exports|import(?:\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\s+)(?!)[a-z]\\w*(?:\\.[a-z]\\w*)*\\.?".replace(//g,function(){return t.source})),lookbehind:!0,inside:{punctuation:/\./}},generics:{pattern:/<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/,inside:{"class-name":a,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}}})}(Prism); +!function(d){function n(n){return n=n.replace(//g,function(){return"(?:\\\\.|[^\\\\\n\r]|(?:\n|\r\n?)(?!\n|\r\n?))"}),RegExp("((?:^|[^\\\\])(?:\\\\{2})*)(?:"+n+")")}var e="(?:\\\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\\\|\r\n`])+",t="\\|?__(?:\\|__)+\\|?(?:(?:\n|\r\n?)|$)".replace(/__/g,function(){return e}),a="\\|?[ \t]*:?-{3,}:?[ \t]*(?:\\|[ \t]*:?-{3,}:?[ \t]*)+\\|?(?:\n|\r\n?)";d.languages.markdown=d.languages.extend("markup",{}),d.languages.insertBefore("markdown","prolog",{blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+t+a+"(?:"+t+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+t+a+")(?:"+t+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(e),inside:d.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+t+")"+a+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+t+"$"),inside:{"table-header":{pattern:RegExp(e),alias:"important",inside:d.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/``.+?``|`[^`\r\n]+`/,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#+.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n("\\b__(?:(?!_)|_(?:(?!_))+_)+__\\b|\\*\\*(?:(?!\\*)|\\*(?:(?!\\*))+\\*)+\\*\\*"),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n("\\b_(?:(?!_)|__(?:(?!_))+__)+_\\b|\\*(?:(?!\\*)|\\*\\*(?:(?!\\*))+\\*\\*)+\\*"),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n("(~~?)(?:(?!~))+?\\2"),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},url:{pattern:n('!?\\[(?:(?!\\]))+\\](?:\\([^\\s)]+(?:[\t ]+"(?:\\\\.|[^"\\\\])*")?\\)| ?\\[(?:(?!\\]))+\\])'),lookbehind:!0,greedy:!0,inside:{variable:{pattern:/(\[)[^\]]+(?=\]$)/,lookbehind:!0},content:{pattern:/(^!?\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},string:{pattern:/"(?:\\.|[^"\\])*"(?=\)$)/}}}}),["url","bold","italic","strike"].forEach(function(e){["url","bold","italic","strike"].forEach(function(n){e!==n&&(d.languages.markdown[e].inside.content.inside[n]=d.languages.markdown[n])})}),d.hooks.add("after-tokenize",function(n){"markdown"!==n.language&&"md"!==n.language||!function n(e){if(e&&"string"!=typeof e)for(var t=0,a=e.length;t]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},Prism.languages.python["string-interpolation"].inside.interpolation.inside.rest=Prism.languages.python,Prism.languages.py=Prism.languages.python; +Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()]|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}]+[:{][^}]+))/m,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[\w-]|\$[-\w]+|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),Prism.languages.insertBefore("scss","atrule",{keyword:[/@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i,{pattern:/( +)(?:from|through)(?= )/,lookbehind:!0}]}),Prism.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),Prism.languages.insertBefore("scss","function",{placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:true|false)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/,lookbehind:!0}}),Prism.languages.scss.atrule.inside.rest=Prism.languages.scss; +Prism.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:S|ING)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:TRUE|FALSE|NULL)\b/i,number:/\b0x[\da-f]+\b|\b\d+\.?\d*|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/}; +!function(e){function n(e){return e.replace(/__/g,function(){return"(?:[\\w-]+|'[^'\n\r]*'|\"(?:\\\\.|[^\\\\\"\r\n])*\")"})}e.languages.toml={comment:{pattern:/#.*/,greedy:!0},table:{pattern:RegExp(n("(^\\s*\\[\\s*(?:\\[\\s*)?)__(?:\\s*\\.\\s*__)*(?=\\s*\\])"),"m"),lookbehind:!0,greedy:!0,alias:"class-name"},key:{pattern:RegExp(n("(^\\s*|[{,]\\s*)__(?:\\s*\\.\\s*__)*(?=\\s*=)"),"m"),lookbehind:!0,greedy:!0,alias:"property"},string:{pattern:/"""(?:\\[\s\S]|[^\\])*?"""|'''[\s\S]*?'''|'[^'\n\r]*'|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},date:[{pattern:/\b\d{4}-\d{2}-\d{2}(?:[T\s]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?)?\b/i,alias:"number"},{pattern:/\b\d{2}:\d{2}:\d{2}(?:\.\d+)?\b/,alias:"number"}],number:/(?:\b0(?:x[\da-zA-Z]+(?:_[\da-zA-Z]+)*|o[0-7]+(?:_[0-7]+)*|b[10]+(?:_[10]+)*))\b|[-+]?\b\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?\b|[-+]?\b(?:inf|nan)\b/,boolean:/\b(?:true|false)\b/,punctuation:/[.,=[\]{}]/}}(Prism); +!function(n){var t=/[*&][^\s[\]{},]+/,e=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+e.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+e.source+")?)";function a(n,t){t=(t||"").replace(/m/g,"")+"m";var e="([:\\-,[{]\\s*(?:\\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|]|}|\\s*#))".replace(/<>/g,function(){return r}).replace(/<>/g,function(){return n});return RegExp(e,t)}n.languages.yaml={scalar:{pattern:RegExp("([\\-:]\\s*(?:\\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\\2[^\r\n]+)*)".replace(/<>/g,function(){return r})),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp("((?:^|[:\\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)[^\r\n{[\\]},#\\s]+?(?=\\s*:\\s)".replace(/<>/g,function(){return r})),lookbehind:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:a("\\d{4}-\\d\\d?-\\d\\d?(?:[tT]|[ \t]+)\\d\\d?:\\d{2}:\\d{2}(?:\\.\\d*)?[ \t]*(?:Z|[-+]\\d\\d?(?::\\d{2})?)?|\\d{4}-\\d{2}-\\d{2}|\\d\\d?:\\d{2}(?::\\d{2}(?:\\.\\d*)?)?"),lookbehind:!0,alias:"number"},boolean:{pattern:a("true|false","i"),lookbehind:!0,alias:"important"},null:{pattern:a("null|~","i"),lookbehind:!0,alias:"important"},string:{pattern:a("(\"|')(?:(?!\\2)[^\\\\\r\n]|\\\\.)*\\2"),lookbehind:!0,greedy:!0},number:{pattern:a("[+-]?(?:0x[\\da-f]+|0o[0-7]+|(?:\\d+\\.?\\d*|\\.?\\d+)(?:e[+-]?\\d+)?|\\.inf|\\.nan)","i"),lookbehind:!0},tag:e,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},n.languages.yml=n.languages.yaml}(Prism); +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var i=[],l={},c=function(){};Prism.plugins.toolbar={};var e=Prism.plugins.toolbar.registerButton=function(e,n){var t;t="function"==typeof n?n:function(e){var t;return"function"==typeof n.onClick?((t=document.createElement("button")).type="button",t.addEventListener("click",function(){n.onClick.call(this,e)})):"string"==typeof n.url?(t=document.createElement("a")).href=n.url:t=document.createElement("span"),n.className&&t.classList.add(n.className),t.textContent=n.text,t},e in l?console.warn('There is a button with the key "'+e+'" registered already.'):i.push(l[e]=t)},t=Prism.plugins.toolbar.hook=function(a){var e=a.element.parentNode;if(e&&/pre/i.test(e.nodeName)&&!e.parentNode.classList.contains("code-toolbar")){var t=document.createElement("div");t.classList.add("code-toolbar"),e.parentNode.insertBefore(t,e),t.appendChild(e);var r=document.createElement("div");r.classList.add("toolbar");var n=i,o=function(e){for(;e;){var t=e.getAttribute("data-toolbar-order");if(null!=t)return(t=t.trim()).length?t.split(/\s*,\s*/g):[];e=e.parentElement}}(a.element);o&&(n=o.map(function(e){return l[e]||c})),n.forEach(function(e){var t=e(a);if(t){var n=document.createElement("div");n.classList.add("toolbar-item"),n.appendChild(t),r.appendChild(n)}}),t.appendChild(r)}};e("label",function(e){var t=e.element.parentNode;if(t&&/pre/i.test(t.nodeName)&&t.hasAttribute("data-label")){var n,a,r=t.getAttribute("data-label");try{a=document.querySelector("template#"+r)}catch(e){}return a?n=a.content:(t.hasAttribute("data-url")?(n=document.createElement("a")).href=t.getAttribute("data-url"):n=document.createElement("span"),n.textContent=r),n}}),Prism.hooks.add("complete",t)}}(); +!function(){if("undefined"!=typeof self&&self.Prism&&self.document)if(Prism.plugins.toolbar){var i=window.ClipboardJS||void 0;i||"function"!=typeof require||(i=require("clipboard"));var c=[];if(!i){var o=document.createElement("script"),t=document.querySelector("head");o.onload=function(){if(i=window.ClipboardJS)for(;c.length;)c.pop()()},o.src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js",t.appendChild(o)}Prism.plugins.toolbar.registerButton("copy-to-clipboard",function(o){var t=document.createElement("button");t.textContent="Copy";var e=o.element;return i?n():c.push(n),t;function n(){var o=new i(t,{text:function(){return e.textContent}});o.on("success",function(){t.textContent="Copied!",r()}),o.on("error",function(){t.textContent="Press Ctrl+C to copy",r()})}function r(){setTimeout(function(){t.textContent="Copy"},5e3)}})}else console.warn("Copy to Clipboard plugin loaded before Toolbar plugin.")}(); diff --git a/js/swagger-ui-bundle.js b/js/swagger-ui-bundle.js new file mode 100644 index 00000000..c48cc4cf --- /dev/null +++ b/js/swagger-ui-bundle.js @@ -0,0 +1,134 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(function(){try{return require("esprima")}catch(e){}}()):"function"==typeof define&&define.amd?define(["esprima"],t):"object"==typeof exports?exports.SwaggerUIBundle=t(function(){try{return require("esprima")}catch(e){}}()):e.SwaggerUIBundle=t(e.esprima)}(window,function(e){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist",n(n.s=488)}([function(e,t,n){"use strict";e.exports=n(104)},function(e,t,n){e.exports=function(){"use strict";var e=Array.prototype.slice;function t(e,t){t&&(e.prototype=Object.create(t.prototype)),e.prototype.constructor=e}function n(e){return a(e)?e:J(e)}function r(e){return s(e)?e:K(e)}function o(e){return u(e)?e:Y(e)}function i(e){return a(e)&&!c(e)?e:$(e)}function a(e){return!(!e||!e[p])}function s(e){return!(!e||!e[f])}function u(e){return!(!e||!e[h])}function c(e){return s(e)||u(e)}function l(e){return!(!e||!e[d])}t(r,n),t(o,n),t(i,n),n.isIterable=a,n.isKeyed=s,n.isIndexed=u,n.isAssociative=c,n.isOrdered=l,n.Keyed=r,n.Indexed=o,n.Set=i;var p="@@__IMMUTABLE_ITERABLE__@@",f="@@__IMMUTABLE_KEYED__@@",h="@@__IMMUTABLE_INDEXED__@@",d="@@__IMMUTABLE_ORDERED__@@",m=5,v=1<>>0;if(""+n!==t||4294967295===n)return NaN;t=n}return t<0?C(e)+t:t}function O(){return!0}function A(e,t,n){return(0===e||void 0!==n&&e<=-n)&&(void 0===t||void 0!==n&&t>=n)}function T(e,t){return P(e,t,0)}function j(e,t){return P(e,t,t)}function P(e,t,n){return void 0===e?n:e<0?Math.max(0,t+e):void 0===t?e:Math.min(t,e)}var I=0,M=1,N=2,R="function"==typeof Symbol&&Symbol.iterator,D="@@iterator",L=R||D;function U(e){this.next=e}function q(e,t,n,r){var o=0===e?t:1===e?n:[t,n];return r?r.value=o:r={value:o,done:!1},r}function F(){return{value:void 0,done:!0}}function B(e){return!!H(e)}function z(e){return e&&"function"==typeof e.next}function V(e){var t=H(e);return t&&t.call(e)}function H(e){var t=e&&(R&&e[R]||e[D]);if("function"==typeof t)return t}function W(e){return e&&"number"==typeof e.length}function J(e){return null==e?ie():a(e)?e.toSeq():function(e){var t=ue(e)||"object"==typeof e&&new te(e);if(!t)throw new TypeError("Expected Array or iterable object of values, or keyed object: "+e);return t}(e)}function K(e){return null==e?ie().toKeyedSeq():a(e)?s(e)?e.toSeq():e.fromEntrySeq():ae(e)}function Y(e){return null==e?ie():a(e)?s(e)?e.entrySeq():e.toIndexedSeq():se(e)}function $(e){return(null==e?ie():a(e)?s(e)?e.entrySeq():e:se(e)).toSetSeq()}U.prototype.toString=function(){return"[Iterator]"},U.KEYS=I,U.VALUES=M,U.ENTRIES=N,U.prototype.inspect=U.prototype.toSource=function(){return this.toString()},U.prototype[L]=function(){return this},t(J,n),J.of=function(){return J(arguments)},J.prototype.toSeq=function(){return this},J.prototype.toString=function(){return this.__toString("Seq {","}")},J.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},J.prototype.__iterate=function(e,t){return ce(this,e,t,!0)},J.prototype.__iterator=function(e,t){return le(this,e,t,!0)},t(K,J),K.prototype.toKeyedSeq=function(){return this},t(Y,J),Y.of=function(){return Y(arguments)},Y.prototype.toIndexedSeq=function(){return this},Y.prototype.toString=function(){return this.__toString("Seq [","]")},Y.prototype.__iterate=function(e,t){return ce(this,e,t,!1)},Y.prototype.__iterator=function(e,t){return le(this,e,t,!1)},t($,J),$.of=function(){return $(arguments)},$.prototype.toSetSeq=function(){return this},J.isSeq=oe,J.Keyed=K,J.Set=$,J.Indexed=Y;var G,Z,X,Q="@@__IMMUTABLE_SEQ__@@";function ee(e){this._array=e,this.size=e.length}function te(e){var t=Object.keys(e);this._object=e,this._keys=t,this.size=t.length}function ne(e){this._iterable=e,this.size=e.length||e.size}function re(e){this._iterator=e,this._iteratorCache=[]}function oe(e){return!(!e||!e[Q])}function ie(){return G||(G=new ee([]))}function ae(e){var t=Array.isArray(e)?new ee(e).fromEntrySeq():z(e)?new re(e).fromEntrySeq():B(e)?new ne(e).fromEntrySeq():"object"==typeof e?new te(e):void 0;if(!t)throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+e);return t}function se(e){var t=ue(e);if(!t)throw new TypeError("Expected Array or iterable object of values: "+e);return t}function ue(e){return W(e)?new ee(e):z(e)?new re(e):B(e)?new ne(e):void 0}function ce(e,t,n,r){var o=e._cache;if(o){for(var i=o.length-1,a=0;a<=i;a++){var s=o[n?i-a:a];if(!1===t(s[1],r?s[0]:a,e))return a+1}return a}return e.__iterateUncached(t,n)}function le(e,t,n,r){var o=e._cache;if(o){var i=o.length-1,a=0;return new U(function(){var e=o[n?i-a:a];return a++>i?{value:void 0,done:!0}:q(t,r?e[0]:a-1,e[1])})}return e.__iteratorUncached(t,n)}function pe(e,t){return t?function e(t,n,r,o){return Array.isArray(n)?t.call(o,r,Y(n).map(function(r,o){return e(t,r,o,n)})):he(n)?t.call(o,r,K(n).map(function(r,o){return e(t,r,o,n)})):n}(t,e,"",{"":e}):fe(e)}function fe(e){return Array.isArray(e)?Y(e).map(fe).toList():he(e)?K(e).map(fe).toMap():e}function he(e){return e&&(e.constructor===Object||void 0===e.constructor)}function de(e,t){if(e===t||e!=e&&t!=t)return!0;if(!e||!t)return!1;if("function"==typeof e.valueOf&&"function"==typeof t.valueOf){if((e=e.valueOf())===(t=t.valueOf())||e!=e&&t!=t)return!0;if(!e||!t)return!1}return!("function"!=typeof e.equals||"function"!=typeof t.equals||!e.equals(t))}function me(e,t){if(e===t)return!0;if(!a(t)||void 0!==e.size&&void 0!==t.size&&e.size!==t.size||void 0!==e.__hash&&void 0!==t.__hash&&e.__hash!==t.__hash||s(e)!==s(t)||u(e)!==u(t)||l(e)!==l(t))return!1;if(0===e.size&&0===t.size)return!0;var n=!c(e);if(l(e)){var r=e.entries();return t.every(function(e,t){var o=r.next().value;return o&&de(o[1],e)&&(n||de(o[0],t))})&&r.next().done}var o=!1;if(void 0===e.size)if(void 0===t.size)"function"==typeof e.cacheResult&&e.cacheResult();else{o=!0;var i=e;e=t,t=i}var p=!0,f=t.__iterate(function(t,r){if(n?!e.has(t):o?!de(t,e.get(r,y)):!de(e.get(r,y),t))return p=!1,!1});return p&&e.size===f}function ve(e,t){if(!(this instanceof ve))return new ve(e,t);if(this._value=e,this.size=void 0===t?1/0:Math.max(0,t),0===this.size){if(Z)return Z;Z=this}}function ge(e,t){if(!e)throw new Error(t)}function ye(e,t,n){if(!(this instanceof ye))return new ye(e,t,n);if(ge(0!==n,"Cannot step a Range by 0"),e=e||0,void 0===t&&(t=1/0),n=void 0===n?1:Math.abs(n),tr?{value:void 0,done:!0}:q(e,o,n[t?r-o++:o++])})},t(te,K),te.prototype.get=function(e,t){return void 0===t||this.has(e)?this._object[e]:t},te.prototype.has=function(e){return this._object.hasOwnProperty(e)},te.prototype.__iterate=function(e,t){for(var n=this._object,r=this._keys,o=r.length-1,i=0;i<=o;i++){var a=r[t?o-i:i];if(!1===e(n[a],a,this))return i+1}return i},te.prototype.__iterator=function(e,t){var n=this._object,r=this._keys,o=r.length-1,i=0;return new U(function(){var a=r[t?o-i:i];return i++>o?{value:void 0,done:!0}:q(e,a,n[a])})},te.prototype[d]=!0,t(ne,Y),ne.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);var n=V(this._iterable),r=0;if(z(n))for(var o;!(o=n.next()).done&&!1!==e(o.value,r++,this););return r},ne.prototype.__iteratorUncached=function(e,t){if(t)return this.cacheResult().__iterator(e,t);var n=V(this._iterable);if(!z(n))return new U(F);var r=0;return new U(function(){var t=n.next();return t.done?t:q(e,r++,t.value)})},t(re,Y),re.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);for(var n,r=this._iterator,o=this._iteratorCache,i=0;i=r.length){var t=n.next();if(t.done)return t;r[o]=t.value}return q(e,o,r[o++])})},t(ve,Y),ve.prototype.toString=function(){return 0===this.size?"Repeat []":"Repeat [ "+this._value+" "+this.size+" times ]"},ve.prototype.get=function(e,t){return this.has(e)?this._value:t},ve.prototype.includes=function(e){return de(this._value,e)},ve.prototype.slice=function(e,t){var n=this.size;return A(e,t,n)?this:new ve(this._value,j(t,n)-T(e,n))},ve.prototype.reverse=function(){return this},ve.prototype.indexOf=function(e){return de(this._value,e)?0:-1},ve.prototype.lastIndexOf=function(e){return de(this._value,e)?this.size:-1},ve.prototype.__iterate=function(e,t){for(var n=0;n=0&&t=0&&nn?{value:void 0,done:!0}:q(e,i++,a)})},ye.prototype.equals=function(e){return e instanceof ye?this._start===e._start&&this._end===e._end&&this._step===e._step:me(this,e)},t(be,n),t(_e,be),t(we,be),t(xe,be),be.Keyed=_e,be.Indexed=we,be.Set=xe;var Ee="function"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function(e,t){var n=65535&(e|=0),r=65535&(t|=0);return n*r+((e>>>16)*r+n*(t>>>16)<<16>>>0)|0};function Se(e){return e>>>1&1073741824|3221225471&e}function Ce(e){if(!1===e||null==e)return 0;if("function"==typeof e.valueOf&&(!1===(e=e.valueOf())||null==e))return 0;if(!0===e)return 1;var t=typeof e;if("number"===t){if(e!=e||e===1/0)return 0;var n=0|e;for(n!==e&&(n^=4294967295*e);e>4294967295;)n^=e/=4294967295;return Se(n)}if("string"===t)return e.length>Me?function(e){var t=De[e];return void 0===t&&(t=ke(e),Re===Ne&&(Re=0,De={}),Re++,De[e]=t),t}(e):ke(e);if("function"==typeof e.hashCode)return e.hashCode();if("object"===t)return function(e){var t;if(je&&void 0!==(t=Oe.get(e)))return t;if(void 0!==(t=e[Ie]))return t;if(!Te){if(void 0!==(t=e.propertyIsEnumerable&&e.propertyIsEnumerable[Ie]))return t;if(void 0!==(t=function(e){if(e&&e.nodeType>0)switch(e.nodeType){case 1:return e.uniqueID;case 9:return e.documentElement&&e.documentElement.uniqueID}}(e)))return t}if(t=++Pe,1073741824&Pe&&(Pe=0),je)Oe.set(e,t);else{if(void 0!==Ae&&!1===Ae(e))throw new Error("Non-extensible objects are not allowed as keys.");if(Te)Object.defineProperty(e,Ie,{enumerable:!1,configurable:!1,writable:!1,value:t});else if(void 0!==e.propertyIsEnumerable&&e.propertyIsEnumerable===e.constructor.prototype.propertyIsEnumerable)e.propertyIsEnumerable=function(){return this.constructor.prototype.propertyIsEnumerable.apply(this,arguments)},e.propertyIsEnumerable[Ie]=t;else{if(void 0===e.nodeType)throw new Error("Unable to set a non-enumerable property on object.");e[Ie]=t}}return t}(e);if("function"==typeof e.toString)return ke(e.toString());throw new Error("Value type "+t+" cannot be hashed.")}function ke(e){for(var t=0,n=0;n=t.length)throw new Error("Missing value for key: "+t[n]);e.set(t[n],t[n+1])}})},Ue.prototype.toString=function(){return this.__toString("Map {","}")},Ue.prototype.get=function(e,t){return this._root?this._root.get(0,void 0,e,t):t},Ue.prototype.set=function(e,t){return Qe(this,e,t)},Ue.prototype.setIn=function(e,t){return this.updateIn(e,y,function(){return t})},Ue.prototype.remove=function(e){return Qe(this,e,y)},Ue.prototype.deleteIn=function(e){return this.updateIn(e,function(){return y})},Ue.prototype.update=function(e,t,n){return 1===arguments.length?e(this):this.updateIn([e],t,n)},Ue.prototype.updateIn=function(e,t,n){n||(n=t,t=void 0);var r=function e(t,n,r,o){var i=t===y,a=n.next();if(a.done){var s=i?r:t,u=o(s);return u===s?t:u}ge(i||t&&t.set,"invalid keyPath");var c=a.value,l=i?y:t.get(c,y),p=e(l,n,r,o);return p===l?t:p===y?t.remove(c):(i?Xe():t).set(c,p)}(this,rn(e),t,n);return r===y?void 0:r},Ue.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):Xe()},Ue.prototype.merge=function(){return rt(this,void 0,arguments)},Ue.prototype.mergeWith=function(t){var n=e.call(arguments,1);return rt(this,t,n)},Ue.prototype.mergeIn=function(t){var n=e.call(arguments,1);return this.updateIn(t,Xe(),function(e){return"function"==typeof e.merge?e.merge.apply(e,n):n[n.length-1]})},Ue.prototype.mergeDeep=function(){return rt(this,ot,arguments)},Ue.prototype.mergeDeepWith=function(t){var n=e.call(arguments,1);return rt(this,it(t),n)},Ue.prototype.mergeDeepIn=function(t){var n=e.call(arguments,1);return this.updateIn(t,Xe(),function(e){return"function"==typeof e.mergeDeep?e.mergeDeep.apply(e,n):n[n.length-1]})},Ue.prototype.sort=function(e){return Tt(Jt(this,e))},Ue.prototype.sortBy=function(e,t){return Tt(Jt(this,t,e))},Ue.prototype.withMutations=function(e){var t=this.asMutable();return e(t),t.wasAltered()?t.__ensureOwner(this.__ownerID):this},Ue.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new E)},Ue.prototype.asImmutable=function(){return this.__ensureOwner()},Ue.prototype.wasAltered=function(){return this.__altered},Ue.prototype.__iterator=function(e,t){return new Ye(this,e,t)},Ue.prototype.__iterate=function(e,t){var n=this,r=0;return this._root&&this._root.iterate(function(t){return r++,e(t[1],t[0],n)},t),r},Ue.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?Ze(this.size,this._root,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},Ue.isMap=qe;var Fe,Be="@@__IMMUTABLE_MAP__@@",ze=Ue.prototype;function Ve(e,t){this.ownerID=e,this.entries=t}function He(e,t,n){this.ownerID=e,this.bitmap=t,this.nodes=n}function We(e,t,n){this.ownerID=e,this.count=t,this.nodes=n}function Je(e,t,n){this.ownerID=e,this.keyHash=t,this.entries=n}function Ke(e,t,n){this.ownerID=e,this.keyHash=t,this.entry=n}function Ye(e,t,n){this._type=t,this._reverse=n,this._stack=e._root&&Ge(e._root)}function $e(e,t){return q(e,t[0],t[1])}function Ge(e,t){return{node:e,index:0,__prev:t}}function Ze(e,t,n,r){var o=Object.create(ze);return o.size=e,o._root=t,o.__ownerID=n,o.__hash=r,o.__altered=!1,o}function Xe(){return Fe||(Fe=Ze(0))}function Qe(e,t,n){var r,o;if(e._root){var i=w(b),a=w(_);if(r=et(e._root,e.__ownerID,0,void 0,t,n,i,a),!a.value)return e;o=e.size+(i.value?n===y?-1:1:0)}else{if(n===y)return e;o=1,r=new Ve(e.__ownerID,[[t,n]])}return e.__ownerID?(e.size=o,e._root=r,e.__hash=void 0,e.__altered=!0,e):r?Ze(o,r):Xe()}function et(e,t,n,r,o,i,a,s){return e?e.update(t,n,r,o,i,a,s):i===y?e:(x(s),x(a),new Ke(t,r,[o,i]))}function tt(e){return e.constructor===Ke||e.constructor===Je}function nt(e,t,n,r,o){if(e.keyHash===r)return new Je(t,r,[e.entry,o]);var i,a=(0===n?e.keyHash:e.keyHash>>>n)&g,s=(0===n?r:r>>>n)&g;return new He(t,1<>1&1431655765))+(e>>2&858993459))+(e>>4)&252645135,e+=e>>8,127&(e+=e>>16)}function ut(e,t,n,r){var o=r?e:S(e);return o[t]=n,o}ze[Be]=!0,ze.delete=ze.remove,ze.removeIn=ze.deleteIn,Ve.prototype.get=function(e,t,n,r){for(var o=this.entries,i=0,a=o.length;i=ct)return function(e,t,n,r){e||(e=new E);for(var o=new Ke(e,Ce(n),[n,r]),i=0;i>>e)&g),i=this.bitmap;return 0==(i&o)?r:this.nodes[st(i&o-1)].get(e+m,t,n,r)},He.prototype.update=function(e,t,n,r,o,i,a){void 0===n&&(n=Ce(r));var s=(0===t?n:n>>>t)&g,u=1<=lt)return function(e,t,n,r,o){for(var i=0,a=new Array(v),s=0;0!==n;s++,n>>>=1)a[s]=1&n?t[i++]:void 0;return a[r]=o,new We(e,i+1,a)}(e,f,c,s,d);if(l&&!d&&2===f.length&&tt(f[1^p]))return f[1^p];if(l&&d&&1===f.length&&tt(d))return d;var b=e&&e===this.ownerID,_=l?d?c:c^u:c|u,w=l?d?ut(f,p,d,b):function(e,t,n){var r=e.length-1;if(n&&t===r)return e.pop(),e;for(var o=new Array(r),i=0,a=0;a>>e)&g,i=this.nodes[o];return i?i.get(e+m,t,n,r):r},We.prototype.update=function(e,t,n,r,o,i,a){void 0===n&&(n=Ce(r));var s=(0===t?n:n>>>t)&g,u=o===y,c=this.nodes,l=c[s];if(u&&!l)return this;var p=et(l,e,t+m,n,r,o,i,a);if(p===l)return this;var f=this.count;if(l){if(!p&&--f0&&r=0&&e=e.size||t<0)return e.withMutations(function(e){t<0?kt(e,t).set(0,n):kt(e,0,t+1).set(t,n)});t+=e._origin;var r=e._tail,o=e._root,i=w(_);return t>=At(e._capacity)?r=Et(r,e.__ownerID,0,t,n,i):o=Et(o,e.__ownerID,e._level,t,n,i),i.value?e.__ownerID?(e._root=o,e._tail=r,e.__hash=void 0,e.__altered=!0,e):wt(e._origin,e._capacity,e._level,o,r):e}(this,e,t)},ft.prototype.remove=function(e){return this.has(e)?0===e?this.shift():e===this.size-1?this.pop():this.splice(e,1):this},ft.prototype.insert=function(e,t){return this.splice(e,0,t)},ft.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=this._origin=this._capacity=0,this._level=m,this._root=this._tail=null,this.__hash=void 0,this.__altered=!0,this):xt()},ft.prototype.push=function(){var e=arguments,t=this.size;return this.withMutations(function(n){kt(n,0,t+e.length);for(var r=0;r>>t&g;if(r>=this.array.length)return new vt([],e);var o,i=0===r;if(t>0){var a=this.array[r];if((o=a&&a.removeBefore(e,t-m,n))===a&&i)return this}if(i&&!o)return this;var s=St(this,e);if(!i)for(var u=0;u>>t&g;if(o>=this.array.length)return this;if(t>0){var i=this.array[o];if((r=i&&i.removeAfter(e,t-m,n))===i&&o===this.array.length-1)return this}var a=St(this,e);return a.array.splice(o+1),r&&(a.array[o]=r),a};var gt,yt,bt={};function _t(e,t){var n=e._origin,r=e._capacity,o=At(r),i=e._tail;return a(e._root,e._level,0);function a(e,s,u){return 0===s?function(e,a){var s=a===o?i&&i.array:e&&e.array,u=a>n?0:n-a,c=r-a;return c>v&&(c=v),function(){if(u===c)return bt;var e=t?--c:u++;return s&&s[e]}}(e,u):function(e,o,i){var s,u=e&&e.array,c=i>n?0:n-i>>o,l=1+(r-i>>o);return l>v&&(l=v),function(){for(;;){if(s){var e=s();if(e!==bt)return e;s=null}if(c===l)return bt;var n=t?--l:c++;s=a(u&&u[n],o-m,i+(n<>>n&g,u=e&&s0){var c=e&&e.array[s],l=Et(c,t,n-m,r,o,i);return l===c?e:((a=St(e,t)).array[s]=l,a)}return u&&e.array[s]===o?e:(x(i),a=St(e,t),void 0===o&&s===a.array.length-1?a.array.pop():a.array[s]=o,a)}function St(e,t){return t&&e&&t===e.ownerID?e:new vt(e?e.array.slice():[],t)}function Ct(e,t){if(t>=At(e._capacity))return e._tail;if(t<1<0;)n=n.array[t>>>r&g],r-=m;return n}}function kt(e,t,n){void 0!==t&&(t|=0),void 0!==n&&(n|=0);var r=e.__ownerID||new E,o=e._origin,i=e._capacity,a=o+t,s=void 0===n?i:n<0?i+n:o+n;if(a===o&&s===i)return e;if(a>=s)return e.clear();for(var u=e._level,c=e._root,l=0;a+l<0;)c=new vt(c&&c.array.length?[void 0,c]:[],r),l+=1<<(u+=m);l&&(a+=l,o+=l,s+=l,i+=l);for(var p=At(i),f=At(s);f>=1<p?new vt([],r):h;if(h&&f>p&&am;y-=m){var b=p>>>y&g;v=v.array[b]=St(v.array[b],r)}v.array[p>>>m&g]=h}if(s=f)a-=f,s-=f,u=m,c=null,d=d&&d.removeBefore(r,0,a);else if(a>o||f>>u&g;if(_!==f>>>u&g)break;_&&(l+=(1<o&&(c=c.removeBefore(r,u,a-l)),c&&fi&&(i=c.size),a(u)||(c=c.map(function(e){return pe(e)})),r.push(c)}return i>e.size&&(e=e.setSize(i)),at(e,t,r)}function At(e){return e>>m<=v&&a.size>=2*i.size?(r=(o=a.filter(function(e,t){return void 0!==e&&s!==t})).toKeyedSeq().map(function(e){return e[0]}).flip().toMap(),e.__ownerID&&(r.__ownerID=o.__ownerID=e.__ownerID)):(r=i.remove(t),o=s===a.size-1?a.pop():a.set(s,void 0))}else if(u){if(n===a.get(s)[1])return e;r=i,o=a.set(s,[t,n])}else r=i.set(t,a.size),o=a.set(a.size,[t,n]);return e.__ownerID?(e.size=r.size,e._map=r,e._list=o,e.__hash=void 0,e):Pt(r,o)}function Nt(e,t){this._iter=e,this._useKeys=t,this.size=e.size}function Rt(e){this._iter=e,this.size=e.size}function Dt(e){this._iter=e,this.size=e.size}function Lt(e){this._iter=e,this.size=e.size}function Ut(e){var t=en(e);return t._iter=e,t.size=e.size,t.flip=function(){return e},t.reverse=function(){var t=e.reverse.apply(this);return t.flip=function(){return e.reverse()},t},t.has=function(t){return e.includes(t)},t.includes=function(t){return e.has(t)},t.cacheResult=tn,t.__iterateUncached=function(t,n){var r=this;return e.__iterate(function(e,n){return!1!==t(n,e,r)},n)},t.__iteratorUncached=function(t,n){if(t===N){var r=e.__iterator(t,n);return new U(function(){var e=r.next();if(!e.done){var t=e.value[0];e.value[0]=e.value[1],e.value[1]=t}return e})}return e.__iterator(t===M?I:M,n)},t}function qt(e,t,n){var r=en(e);return r.size=e.size,r.has=function(t){return e.has(t)},r.get=function(r,o){var i=e.get(r,y);return i===y?o:t.call(n,i,r,e)},r.__iterateUncached=function(r,o){var i=this;return e.__iterate(function(e,o,a){return!1!==r(t.call(n,e,o,a),o,i)},o)},r.__iteratorUncached=function(r,o){var i=e.__iterator(N,o);return new U(function(){var o=i.next();if(o.done)return o;var a=o.value,s=a[0];return q(r,s,t.call(n,a[1],s,e),o)})},r}function Ft(e,t){var n=en(e);return n._iter=e,n.size=e.size,n.reverse=function(){return e},e.flip&&(n.flip=function(){var t=Ut(e);return t.reverse=function(){return e.flip()},t}),n.get=function(n,r){return e.get(t?n:-1-n,r)},n.has=function(n){return e.has(t?n:-1-n)},n.includes=function(t){return e.includes(t)},n.cacheResult=tn,n.__iterate=function(t,n){var r=this;return e.__iterate(function(e,n){return t(e,n,r)},!n)},n.__iterator=function(t,n){return e.__iterator(t,!n)},n}function Bt(e,t,n,r){var o=en(e);return r&&(o.has=function(r){var o=e.get(r,y);return o!==y&&!!t.call(n,o,r,e)},o.get=function(r,o){var i=e.get(r,y);return i!==y&&t.call(n,i,r,e)?i:o}),o.__iterateUncached=function(o,i){var a=this,s=0;return e.__iterate(function(e,i,u){if(t.call(n,e,i,u))return s++,o(e,r?i:s-1,a)},i),s},o.__iteratorUncached=function(o,i){var a=e.__iterator(N,i),s=0;return new U(function(){for(;;){var i=a.next();if(i.done)return i;var u=i.value,c=u[0],l=u[1];if(t.call(n,l,c,e))return q(o,r?c:s++,l,i)}})},o}function zt(e,t,n,r){var o=e.size;if(void 0!==t&&(t|=0),void 0!==n&&(n===1/0?n=o:n|=0),A(t,n,o))return e;var i=T(t,o),a=j(n,o);if(i!=i||a!=a)return zt(e.toSeq().cacheResult(),t,n,r);var s,u=a-i;u==u&&(s=u<0?0:u);var c=en(e);return c.size=0===s?s:e.size&&s||void 0,!r&&oe(e)&&s>=0&&(c.get=function(t,n){return(t=k(this,t))>=0&&ts)return{value:void 0,done:!0};var e=o.next();return r||t===M?e:q(t,u-1,t===I?void 0:e.value[1],e)})},c}function Vt(e,t,n,r){var o=en(e);return o.__iterateUncached=function(o,i){var a=this;if(i)return this.cacheResult().__iterate(o,i);var s=!0,u=0;return e.__iterate(function(e,i,c){if(!s||!(s=t.call(n,e,i,c)))return u++,o(e,r?i:u-1,a)}),u},o.__iteratorUncached=function(o,i){var a=this;if(i)return this.cacheResult().__iterator(o,i);var s=e.__iterator(N,i),u=!0,c=0;return new U(function(){var e,i,l;do{if((e=s.next()).done)return r||o===M?e:q(o,c++,o===I?void 0:e.value[1],e);var p=e.value;i=p[0],l=p[1],u&&(u=t.call(n,l,i,a))}while(u);return o===N?e:q(o,i,l,e)})},o}function Ht(e,t){var n=s(e),o=[e].concat(t).map(function(e){return a(e)?n&&(e=r(e)):e=n?ae(e):se(Array.isArray(e)?e:[e]),e}).filter(function(e){return 0!==e.size});if(0===o.length)return e;if(1===o.length){var i=o[0];if(i===e||n&&s(i)||u(e)&&u(i))return i}var c=new ee(o);return n?c=c.toKeyedSeq():u(e)||(c=c.toSetSeq()),(c=c.flatten(!0)).size=o.reduce(function(e,t){if(void 0!==e){var n=t.size;if(void 0!==n)return e+n}},0),c}function Wt(e,t,n){var r=en(e);return r.__iterateUncached=function(r,o){var i=0,s=!1;return function e(u,c){var l=this;u.__iterate(function(o,u){return(!t||c0}function $t(e,t,r){var o=en(e);return o.size=new ee(r).map(function(e){return e.size}).min(),o.__iterate=function(e,t){for(var n,r=this.__iterator(M,t),o=0;!(n=r.next()).done&&!1!==e(n.value,o++,this););return o},o.__iteratorUncached=function(e,o){var i=r.map(function(e){return e=n(e),V(o?e.reverse():e)}),a=0,s=!1;return new U(function(){var n;return s||(n=i.map(function(e){return e.next()}),s=n.some(function(e){return e.done})),s?{value:void 0,done:!0}:q(e,a++,t.apply(null,n.map(function(e){return e.value})))})},o}function Gt(e,t){return oe(e)?t:e.constructor(t)}function Zt(e){if(e!==Object(e))throw new TypeError("Expected [K, V] tuple: "+e)}function Xt(e){return Le(e.size),C(e)}function Qt(e){return s(e)?r:u(e)?o:i}function en(e){return Object.create((s(e)?K:u(e)?Y:$).prototype)}function tn(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):J.prototype.cacheResult.call(this)}function nn(e,t){return e>t?1:e=0;n--)t={value:arguments[n],next:t};return this.__ownerID?(this.size=e,this._head=t,this.__hash=void 0,this.__altered=!0,this):An(e,t)},En.prototype.pushAll=function(e){if(0===(e=o(e)).size)return this;Le(e.size);var t=this.size,n=this._head;return e.reverse().forEach(function(e){t++,n={value:e,next:n}}),this.__ownerID?(this.size=t,this._head=n,this.__hash=void 0,this.__altered=!0,this):An(t,n)},En.prototype.pop=function(){return this.slice(1)},En.prototype.unshift=function(){return this.push.apply(this,arguments)},En.prototype.unshiftAll=function(e){return this.pushAll(e)},En.prototype.shift=function(){return this.pop.apply(this,arguments)},En.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):Tn()},En.prototype.slice=function(e,t){if(A(e,t,this.size))return this;var n=T(e,this.size);if(j(t,this.size)!==this.size)return we.prototype.slice.call(this,e,t);for(var r=this.size-n,o=this._head;n--;)o=o.next;return this.__ownerID?(this.size=r,this._head=o,this.__hash=void 0,this.__altered=!0,this):An(r,o)},En.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?An(this.size,this._head,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},En.prototype.__iterate=function(e,t){if(t)return this.reverse().__iterate(e);for(var n=0,r=this._head;r&&!1!==e(r.value,n++,this);)r=r.next;return n},En.prototype.__iterator=function(e,t){if(t)return this.reverse().__iterator(e);var n=0,r=this._head;return new U(function(){if(r){var t=r.value;return r=r.next,q(e,n++,t)}return{value:void 0,done:!0}})},En.isStack=Sn;var Cn,kn="@@__IMMUTABLE_STACK__@@",On=En.prototype;function An(e,t,n,r){var o=Object.create(On);return o.size=e,o._head=t,o.__ownerID=n,o.__hash=r,o.__altered=!1,o}function Tn(){return Cn||(Cn=An(0))}function jn(e,t){var n=function(n){e.prototype[n]=t[n]};return Object.keys(t).forEach(n),Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(t).forEach(n),e}On[kn]=!0,On.withMutations=ze.withMutations,On.asMutable=ze.asMutable,On.asImmutable=ze.asImmutable,On.wasAltered=ze.wasAltered,n.Iterator=U,jn(n,{toArray:function(){Le(this.size);var e=new Array(this.size||0);return this.valueSeq().__iterate(function(t,n){e[n]=t}),e},toIndexedSeq:function(){return new Rt(this)},toJS:function(){return this.toSeq().map(function(e){return e&&"function"==typeof e.toJS?e.toJS():e}).__toJS()},toJSON:function(){return this.toSeq().map(function(e){return e&&"function"==typeof e.toJSON?e.toJSON():e}).__toJS()},toKeyedSeq:function(){return new Nt(this,!0)},toMap:function(){return Ue(this.toKeyedSeq())},toObject:function(){Le(this.size);var e={};return this.__iterate(function(t,n){e[n]=t}),e},toOrderedMap:function(){return Tt(this.toKeyedSeq())},toOrderedSet:function(){return gn(s(this)?this.valueSeq():this)},toSet:function(){return cn(s(this)?this.valueSeq():this)},toSetSeq:function(){return new Dt(this)},toSeq:function(){return u(this)?this.toIndexedSeq():s(this)?this.toKeyedSeq():this.toSetSeq()},toStack:function(){return En(s(this)?this.valueSeq():this)},toList:function(){return ft(s(this)?this.valueSeq():this)},toString:function(){return"[Iterable]"},__toString:function(e,t){return 0===this.size?e+t:e+" "+this.toSeq().map(this.__toStringMapper).join(", ")+" "+t},concat:function(){var t=e.call(arguments,0);return Gt(this,Ht(this,t))},includes:function(e){return this.some(function(t){return de(t,e)})},entries:function(){return this.__iterator(N)},every:function(e,t){Le(this.size);var n=!0;return this.__iterate(function(r,o,i){if(!e.call(t,r,o,i))return n=!1,!1}),n},filter:function(e,t){return Gt(this,Bt(this,e,t,!0))},find:function(e,t,n){var r=this.findEntry(e,t);return r?r[1]:n},forEach:function(e,t){return Le(this.size),this.__iterate(t?e.bind(t):e)},join:function(e){Le(this.size),e=void 0!==e?""+e:",";var t="",n=!0;return this.__iterate(function(r){n?n=!1:t+=e,t+=null!=r?r.toString():""}),t},keys:function(){return this.__iterator(I)},map:function(e,t){return Gt(this,qt(this,e,t))},reduce:function(e,t,n){var r,o;return Le(this.size),arguments.length<2?o=!0:r=t,this.__iterate(function(t,i,a){o?(o=!1,r=t):r=e.call(n,r,t,i,a)}),r},reduceRight:function(e,t,n){var r=this.toKeyedSeq().reverse();return r.reduce.apply(r,arguments)},reverse:function(){return Gt(this,Ft(this,!0))},slice:function(e,t){return Gt(this,zt(this,e,t,!0))},some:function(e,t){return!this.every(Rn(e),t)},sort:function(e){return Gt(this,Jt(this,e))},values:function(){return this.__iterator(M)},butLast:function(){return this.slice(0,-1)},isEmpty:function(){return void 0!==this.size?0===this.size:!this.some(function(){return!0})},count:function(e,t){return C(e?this.toSeq().filter(e,t):this)},countBy:function(e,t){return function(e,t,n){var r=Ue().asMutable();return e.__iterate(function(o,i){r.update(t.call(n,o,i,e),0,function(e){return e+1})}),r.asImmutable()}(this,e,t)},equals:function(e){return me(this,e)},entrySeq:function(){var e=this;if(e._cache)return new ee(e._cache);var t=e.toSeq().map(Nn).toIndexedSeq();return t.fromEntrySeq=function(){return e.toSeq()},t},filterNot:function(e,t){return this.filter(Rn(e),t)},findEntry:function(e,t,n){var r=n;return this.__iterate(function(n,o,i){if(e.call(t,n,o,i))return r=[o,n],!1}),r},findKey:function(e,t){var n=this.findEntry(e,t);return n&&n[0]},findLast:function(e,t,n){return this.toKeyedSeq().reverse().find(e,t,n)},findLastEntry:function(e,t,n){return this.toKeyedSeq().reverse().findEntry(e,t,n)},findLastKey:function(e,t){return this.toKeyedSeq().reverse().findKey(e,t)},first:function(){return this.find(O)},flatMap:function(e,t){return Gt(this,function(e,t,n){var r=Qt(e);return e.toSeq().map(function(o,i){return r(t.call(n,o,i,e))}).flatten(!0)}(this,e,t))},flatten:function(e){return Gt(this,Wt(this,e,!0))},fromEntrySeq:function(){return new Lt(this)},get:function(e,t){return this.find(function(t,n){return de(n,e)},void 0,t)},getIn:function(e,t){for(var n,r=this,o=rn(e);!(n=o.next()).done;){var i=n.value;if((r=r&&r.get?r.get(i,y):y)===y)return t}return r},groupBy:function(e,t){return function(e,t,n){var r=s(e),o=(l(e)?Tt():Ue()).asMutable();e.__iterate(function(i,a){o.update(t.call(n,i,a,e),function(e){return(e=e||[]).push(r?[a,i]:i),e})});var i=Qt(e);return o.map(function(t){return Gt(e,i(t))})}(this,e,t)},has:function(e){return this.get(e,y)!==y},hasIn:function(e){return this.getIn(e,y)!==y},isSubset:function(e){return e="function"==typeof e.includes?e:n(e),this.every(function(t){return e.includes(t)})},isSuperset:function(e){return(e="function"==typeof e.isSubset?e:n(e)).isSubset(this)},keyOf:function(e){return this.findKey(function(t){return de(t,e)})},keySeq:function(){return this.toSeq().map(Mn).toIndexedSeq()},last:function(){return this.toSeq().reverse().first()},lastKeyOf:function(e){return this.toKeyedSeq().reverse().keyOf(e)},max:function(e){return Kt(this,e)},maxBy:function(e,t){return Kt(this,t,e)},min:function(e){return Kt(this,e?Dn(e):qn)},minBy:function(e,t){return Kt(this,t?Dn(t):qn,e)},rest:function(){return this.slice(1)},skip:function(e){return this.slice(Math.max(0,e))},skipLast:function(e){return Gt(this,this.toSeq().reverse().skip(e).reverse())},skipWhile:function(e,t){return Gt(this,Vt(this,e,t,!0))},skipUntil:function(e,t){return this.skipWhile(Rn(e),t)},sortBy:function(e,t){return Gt(this,Jt(this,t,e))},take:function(e){return this.slice(0,Math.max(0,e))},takeLast:function(e){return Gt(this,this.toSeq().reverse().take(e).reverse())},takeWhile:function(e,t){return Gt(this,function(e,t,n){var r=en(e);return r.__iterateUncached=function(r,o){var i=this;if(o)return this.cacheResult().__iterate(r,o);var a=0;return e.__iterate(function(e,o,s){return t.call(n,e,o,s)&&++a&&r(e,o,i)}),a},r.__iteratorUncached=function(r,o){var i=this;if(o)return this.cacheResult().__iterator(r,o);var a=e.__iterator(N,o),s=!0;return new U(function(){if(!s)return{value:void 0,done:!0};var e=a.next();if(e.done)return e;var o=e.value,u=o[0],c=o[1];return t.call(n,c,u,i)?r===N?e:q(r,u,c,e):(s=!1,{value:void 0,done:!0})})},r}(this,e,t))},takeUntil:function(e,t){return this.takeWhile(Rn(e),t)},valueSeq:function(){return this.toIndexedSeq()},hashCode:function(){return this.__hash||(this.__hash=function(e){if(e.size===1/0)return 0;var t=l(e),n=s(e),r=t?1:0;return function(e,t){return t=Ee(t,3432918353),t=Ee(t<<15|t>>>-15,461845907),t=Ee(t<<13|t>>>-13,5),t=Ee((t=(t+3864292196|0)^e)^t>>>16,2246822507),t=Se((t=Ee(t^t>>>13,3266489909))^t>>>16)}(e.__iterate(n?t?function(e,t){r=31*r+Fn(Ce(e),Ce(t))|0}:function(e,t){r=r+Fn(Ce(e),Ce(t))|0}:t?function(e){r=31*r+Ce(e)|0}:function(e){r=r+Ce(e)|0}),r)}(this))}});var Pn=n.prototype;Pn[p]=!0,Pn[L]=Pn.values,Pn.__toJS=Pn.toArray,Pn.__toStringMapper=Ln,Pn.inspect=Pn.toSource=function(){return this.toString()},Pn.chain=Pn.flatMap,Pn.contains=Pn.includes,jn(r,{flip:function(){return Gt(this,Ut(this))},mapEntries:function(e,t){var n=this,r=0;return Gt(this,this.toSeq().map(function(o,i){return e.call(t,[i,o],r++,n)}).fromEntrySeq())},mapKeys:function(e,t){var n=this;return Gt(this,this.toSeq().flip().map(function(r,o){return e.call(t,r,o,n)}).flip())}});var In=r.prototype;function Mn(e,t){return t}function Nn(e,t){return[t,e]}function Rn(e){return function(){return!e.apply(this,arguments)}}function Dn(e){return function(){return-e.apply(this,arguments)}}function Ln(e){return"string"==typeof e?JSON.stringify(e):String(e)}function Un(){return S(arguments)}function qn(e,t){return et?-1:0}function Fn(e,t){return e^t+2654435769+(e<<6)+(e>>2)|0}return In[f]=!0,In[L]=Pn.entries,In.__toJS=Pn.toObject,In.__toStringMapper=function(e,t){return JSON.stringify(t)+": "+Ln(e)},jn(o,{toKeyedSeq:function(){return new Nt(this,!1)},filter:function(e,t){return Gt(this,Bt(this,e,t,!1))},findIndex:function(e,t){var n=this.findEntry(e,t);return n?n[0]:-1},indexOf:function(e){var t=this.keyOf(e);return void 0===t?-1:t},lastIndexOf:function(e){var t=this.lastKeyOf(e);return void 0===t?-1:t},reverse:function(){return Gt(this,Ft(this,!1))},slice:function(e,t){return Gt(this,zt(this,e,t,!1))},splice:function(e,t){var n=arguments.length;if(t=Math.max(0|t,0),0===n||2===n&&!t)return this;e=T(e,e<0?this.count():this.size);var r=this.slice(0,e);return Gt(this,1===n?r:r.concat(S(arguments,2),this.slice(e+t)))},findLastIndex:function(e,t){var n=this.findLastEntry(e,t);return n?n[0]:-1},first:function(){return this.get(0)},flatten:function(e){return Gt(this,Wt(this,e,!1))},get:function(e,t){return(e=k(this,e))<0||this.size===1/0||void 0!==this.size&&e>this.size?t:this.find(function(t,n){return n===e},void 0,t)},has:function(e){return(e=k(this,e))>=0&&(void 0!==this.size?this.size===1/0||e5e3)return e.textContent;return function(e){for(var n,r,o,i,a,s=e.textContent,u=0,c=s[0],l=1,p=e.innerHTML="",f=0;r=n,n=f<7&&"\\"==n?1:l;){if(l=c,c=s[++u],i=p.length>1,!l||f>8&&"\n"==l||[/\S/.test(l),1,1,!/[$\w]/.test(l),("/"==n||"\n"==n)&&i,'"'==n&&i,"'"==n&&i,s[u-4]+r+n=="--\x3e",r+n=="*/"][f])for(p&&(e.appendChild(a=t.createElement("span")).setAttribute("style",["color: #555; font-weight: bold;","","","color: #555;",""][f?f<3?2:f>6?4:f>3?3:+/^(a(bstract|lias|nd|rguments|rray|s(m|sert)?|uto)|b(ase|egin|ool(ean)?|reak|yte)|c(ase|atch|har|hecked|lass|lone|ompl|onst|ontinue)|de(bugger|cimal|clare|f(ault|er)?|init|l(egate|ete)?)|do|double|e(cho|ls?if|lse(if)?|nd|nsure|num|vent|x(cept|ec|p(licit|ort)|te(nds|nsion|rn)))|f(allthrough|alse|inal(ly)?|ixed|loat|or(each)?|riend|rom|unc(tion)?)|global|goto|guard|i(f|mp(lements|licit|ort)|n(it|clude(_once)?|line|out|stanceof|t(erface|ernal)?)?|s)|l(ambda|et|ock|ong)|m(icrolight|odule|utable)|NaN|n(amespace|ative|ext|ew|il|ot|ull)|o(bject|perator|r|ut|verride)|p(ackage|arams|rivate|rotected|rotocol|ublic)|r(aise|e(adonly|do|f|gister|peat|quire(_once)?|scue|strict|try|turn))|s(byte|ealed|elf|hort|igned|izeof|tatic|tring|truct|ubscript|uper|ynchronized|witch)|t(emplate|hen|his|hrows?|ransient|rue|ry|ype(alias|def|id|name|of))|u(n(checked|def(ined)?|ion|less|signed|til)|se|sing)|v(ar|irtual|oid|olatile)|w(char_t|hen|here|hile|ith)|xor|yield)$/.test(p):0]),a.appendChild(t.createTextNode(p))),o=f&&f<7?f:o,p="",f=11;![1,/[\/{}[(\-+*=<>:;|\\.,?!&@~]/.test(l),/[\])]/.test(l),/[$\w]/.test(l),"/"==l&&o<2&&"<"!=n,'"'==l,"'"==l,l+c+s[u+1]+s[u+2]=="\x3c!--",l+c=="/*",l+c=="//","#"==l][--f];);p+=l}}(e)}function Q(e){var t;if([/filename\*=[^']+'\w*'"([^"]+)";?/i,/filename\*=[^']+'\w*'([^;]+);?/i,/filename="([^;]*);?"/i,/filename=([^;]*);?/i].some(function(n){return null!==(t=n.exec(e))}),null!==t&&t.length>1)try{return decodeURIComponent(t[1])}catch(e){console.error(e)}return null}function ee(e){return t=e.replace(/\.[^.\/]*$/,""),b()(g()(t));var t}var te=function(e,t){if(e>t)return"Value must be less than Maximum"},ne=function(e,t){if(et)return"Value must be less than MaxLength"},pe=function(e,t){if(e.length2&&void 0!==arguments[2]?arguments[2]:{},r=n.isOAS3,o=void 0!==r&&r,i=n.bypassRequiredCheck,a=void 0!==i&&i,s=[],u=e.get("required"),c=Object(P.a)(e,{isOAS3:o}),p=c.schema,h=c.parameterContentMediaType;if(!p)return s;var m=p.get("required"),v=p.get("maximum"),g=p.get("minimum"),y=p.get("type"),b=p.get("format"),_=p.get("maxLength"),w=p.get("minLength"),x=p.get("pattern");if(y&&(u||m||t)){var E="string"===y&&t,S="array"===y&&l()(t)&&t.length,C="array"===y&&d.a.List.isList(t)&&t.count(),k="array"===y&&"string"==typeof t&&t,O="file"===y&&t instanceof A.a.File,T="boolean"===y&&(t||!1===t),j="number"===y&&(t||0===t),I="integer"===y&&(t||0===t),M="object"===y&&"object"===f()(t)&&null!==t,N="object"===y&&"string"==typeof t&&t,R=[E,S,C,k,O,T,j,I,M,N],D=R.some(function(e){return!!e});if((u||m)&&!D&&!a)return s.push("Required field is not provided"),s;if("object"===y&&"string"==typeof t&&(null===h||"application/json"===h))try{JSON.parse(t)}catch(e){return s.push("Parameter string value must be valid JSON"),s}if(x){var L=fe(t,x);L&&s.push(L)}if(_||0===_){var U=le(t,_);U&&s.push(U)}if(w){var q=pe(t,w);q&&s.push(q)}if(v||0===v){var F=te(t,v);F&&s.push(F)}if(g||0===g){var B=ne(t,g);B&&s.push(B)}if("string"===y){var z;if(!(z="date-time"===b?ue(t):"uuid"===b?ce(t):se(t)))return s;s.push(z)}else if("boolean"===y){var V=ae(t);if(!V)return s;s.push(V)}else if("number"===y){var H=re(t);if(!H)return s;s.push(H)}else if("integer"===y){var W=oe(t);if(!W)return s;s.push(W)}else if("array"===y){var J;if(!C||!t.count())return s;J=p.getIn(["items","type"]),t.forEach(function(e,t){var n;"number"===J?n=re(e):"integer"===J?n=oe(e):"string"===J&&(n=se(e)),n&&s.push({index:t,error:n})})}else if("file"===y){var K=ie(t);if(!K)return s;s.push(K)}}return s},de=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(/xml/.test(t)){if(!e.xml||!e.xml.name){if(e.xml=e.xml||{},!e.$$ref)return e.type||e.items||e.properties||e.additionalProperties?'\n\x3c!-- XML example cannot be generated; root element name is undefined --\x3e':null;var r=e.$$ref.match(/\S*\/(\S+)$/);e.xml.name=r[1]}return Object(k.memoizedCreateXMLExample)(e,n)}var i=Object(k.memoizedSampleFromSchema)(e,n);return"object"===f()(i)?o()(i,null,2):i},me=function(){var e={},t=A.a.location.search;if(!t)return{};if(""!=t){var n=t.substr(1).split("&");for(var r in n)n.hasOwnProperty(r)&&(r=n[r].split("="),e[decodeURIComponent(r[0])]=r[1]&&decodeURIComponent(r[1])||"")}return e},ve=function(t){return(t instanceof e?t:new e(t.toString(),"utf-8")).toString("base64")},ge={operationsSorter:{alpha:function(e,t){return e.get("path").localeCompare(t.get("path"))},method:function(e,t){return e.get("method").localeCompare(t.get("method"))}},tagsSorter:{alpha:function(e,t){return e.localeCompare(t)}}},ye=function(e){var t=[];for(var n in e){var r=e[n];void 0!==r&&""!==r&&t.push([n,"=",encodeURIComponent(r).replace(/%20/g,"+")].join(""))}return t.join("&")},be=function(e,t,n){return!!E()(n,function(n){return C()(e[n],t[n])})};function _e(e){return"string"!=typeof e||""===e?"":Object(m.sanitizeUrl)(e)}function we(e){if(!d.a.OrderedMap.isOrderedMap(e))return null;if(!e.size)return null;var t=e.find(function(e,t){return t.startsWith("2")&&u()(e.get("content")||{}).length>0}),n=e.get("default")||d.a.OrderedMap(),r=(n.get("content")||d.a.OrderedMap()).keySeq().toJS().length?n:null;return t||r}var xe=function(e){return"string"==typeof e||e instanceof String?e.trim().replace(/\s/g,"%20"):""},Ee=function(e){return j()(xe(e).replace(/%20/g,"_"))},Se=function(e){return e.filter(function(e,t){return/^x-/.test(t)})},Ce=function(e){return e.filter(function(e,t){return/^pattern|maxLength|minLength|maximum|minimum/.test(t)})};function ke(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){return!0};if("object"!==f()(e)||l()(e)||null===e||!t)return e;var r=a()({},e);return u()(r).forEach(function(e){e===t&&n(r[e],e)?delete r[e]:r[e]=ke(r[e],t,n)}),r}function Oe(e){if("string"==typeof e)return e;if(e&&e.toJS&&(e=e.toJS()),"object"===f()(e)&&null!==e)try{return o()(e,null,2)}catch(t){return String(e)}return null==e?"":e.toString()}function Ae(e){return"number"==typeof e?e.toString():e}function Te(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.returnAll,r=void 0!==n&&n,o=t.allowHashes,i=void 0===o||o;if(!d.a.Map.isMap(e))throw new Error("paramToIdentifier: received a non-Im.Map parameter as input");var a=e.get("name"),s=e.get("in"),u=[];return e&&e.hashCode&&s&&a&&i&&u.push("".concat(s,".").concat(a,".hash-").concat(e.hashCode())),s&&a&&u.push("".concat(s,".").concat(a)),u.push(a),r?u:u[0]||""}function je(e,t){return Te(e,{returnAll:!0}).map(function(e){return t[e]}).filter(function(e){return void 0!==e})[0]}function Pe(){return Me(M()(32).toString("base64"))}function Ie(e){return Me(R()("sha256").update(e).digest("base64"))}function Me(e){return e.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}}).call(this,n(64).Buffer)},function(e,t){e.exports=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}},function(e,t,n){var r=n(54);function o(e,t){for(var n=0;n1?t-1:0),o=1;o2?n-2:0),i=2;i>",i={listOf:function(e){return c(e,"List",r.List.isList)},mapOf:function(e,t){return l(e,t,"Map",r.Map.isMap)},orderedMapOf:function(e,t){return l(e,t,"OrderedMap",r.OrderedMap.isOrderedMap)},setOf:function(e){return c(e,"Set",r.Set.isSet)},orderedSetOf:function(e){return c(e,"OrderedSet",r.OrderedSet.isOrderedSet)},stackOf:function(e){return c(e,"Stack",r.Stack.isStack)},iterableOf:function(e){return c(e,"Iterable",r.Iterable.isIterable)},recordOf:function(e){return s(function(t,n,o,i,s){for(var u=arguments.length,c=Array(u>5?u-5:0),l=5;l6?u-6:0),l=6;l5?c-5:0),p=5;p5?i-5:0),s=5;s key("+l[p]+")"].concat(a));if(h instanceof Error)return h}})).apply(void 0,i);var u})}function p(e){var t=void 0===arguments[1]?"Iterable":arguments[1],n=void 0===arguments[2]?r.Iterable.isIterable:arguments[2];return s(function(r,o,i,s,u){for(var c=arguments.length,l=Array(c>5?c-5:0),p=5;p4)}function u(e){var t=e.get("swagger");return"string"==typeof t&&t.startsWith("2.0")}function c(e){return function(t,n){return function(r){return n&&n.specSelectors&&n.specSelectors.specJson?s(n.specSelectors.specJson())?a.a.createElement(e,o()({},r,n,{Ori:t})):a.a.createElement(t,r):(console.warn("OAS3 wrapper: couldn't get spec"),null)}}}},function(e,t,n){"use strict"; +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/var r=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable;function a(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach(function(e){r[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,s,u=a(e),c=1;c0){var o=n.map(function(e){return console.error(e),e.line=e.fullPath?g(y,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",A()(e,"message",{enumerable:!0,value:e.message}),e});i.newThrownErrBatch(o)}return r.updateResolved(t)})}},_e=[],we=V()(k()(S.a.mark(function e(){var t,n,r,o,i,a,s,u,c,l,p,f,h,d,m,v,g;return S.a.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(t=_e.system){e.next=4;break}return console.error("debResolveSubtrees: don't have a system to operate on, aborting."),e.abrupt("return");case 4:if(n=t.errActions,r=t.errSelectors,o=t.fn,i=o.resolveSubtree,a=o.AST,s=void 0===a?{}:a,u=t.specSelectors,c=t.specActions,i){e.next=8;break}return console.error("Error: Swagger-Client did not provide a `resolveSubtree` method, doing nothing."),e.abrupt("return");case 8:return l=s.getLineNumberForPath?s.getLineNumberForPath:function(){},p=u.specStr(),f=t.getConfigs(),h=f.modelPropertyMacro,d=f.parameterMacro,m=f.requestInterceptor,v=f.responseInterceptor,e.prev=11,e.next=14,_e.reduce(function(){var e=k()(S.a.mark(function e(t,o){var a,s,c,f,g,y,b;return S.a.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,t;case 2:return a=e.sent,s=a.resultMap,c=a.specWithCurrentSubtrees,e.next=7,i(c,o,{baseDoc:u.url(),modelPropertyMacro:h,parameterMacro:d,requestInterceptor:m,responseInterceptor:v});case 7:return f=e.sent,g=f.errors,y=f.spec,r.allErrors().size&&n.clearBy(function(e){return"thrown"!==e.get("type")||"resolver"!==e.get("source")||!e.get("fullPath").every(function(e,t){return e===o[t]||void 0===o[t]})}),j()(g)&&g.length>0&&(b=g.map(function(e){return e.line=e.fullPath?l(p,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",A()(e,"message",{enumerable:!0,value:e.message}),e}),n.newThrownErrBatch(b)),W()(s,o,y),W()(c,o,y),e.abrupt("return",{resultMap:s,specWithCurrentSubtrees:c});case 15:case"end":return e.stop()}},e)}));return function(t,n){return e.apply(this,arguments)}}(),x.a.resolve({resultMap:(u.specResolvedSubtree([])||Object(R.Map)()).toJS(),specWithCurrentSubtrees:u.specJson().toJS()}));case 14:g=e.sent,delete _e.system,_e=[],e.next=22;break;case 19:e.prev=19,e.t0=e.catch(11),console.error(e.t0);case 22:c.updateResolvedSubtree([],g.resultMap);case 23:case"end":return e.stop()}},e,null,[[11,19]])})),35),xe=function(e){return function(t){_e.map(function(e){return e.join("@@")}).indexOf(e.join("@@"))>-1||(_e.push(e),_e.system=t,we())}};function Ee(e,t,n,r,o){return{type:X,payload:{path:e,value:r,paramName:t,paramIn:n,isXml:o}}}function Se(e,t,n,r){return{type:X,payload:{path:e,param:t,value:n,isXml:r}}}var Ce=function(e,t){return{type:le,payload:{path:e,value:t}}},ke=function(){return{type:le,payload:{path:[],value:Object(R.Map)()}}},Oe=function(e,t){return{type:ee,payload:{pathMethod:e,isOAS3:t}}},Ae=function(e,t,n,r){return{type:Q,payload:{pathMethod:e,paramName:t,paramIn:n,includeEmptyValue:r}}};function Te(e){return{type:se,payload:{pathMethod:e}}}function je(e,t){return{type:ue,payload:{path:e,value:t,key:"consumes_value"}}}function Pe(e,t){return{type:ue,payload:{path:e,value:t,key:"produces_value"}}}var Ie=function(e,t,n){return{payload:{path:e,method:t,res:n},type:te}},Me=function(e,t,n){return{payload:{path:e,method:t,req:n},type:ne}},Ne=function(e,t,n){return{payload:{path:e,method:t,req:n},type:re}},Re=function(e){return{payload:e,type:oe}},De=function(e){return function(t){var n=t.fn,r=t.specActions,o=t.specSelectors,i=t.getConfigs,a=t.oas3Selectors,s=e.pathName,u=e.method,c=e.operation,l=i(),p=l.requestInterceptor,f=l.responseInterceptor,h=c.toJS();if(c&&c.get("parameters")&&c.get("parameters").filter(function(e){return e&&!0===e.get("allowEmptyValue")}).forEach(function(t){if(o.parameterInclusionSettingFor([s,u],t.get("name"),t.get("in"))){e.parameters=e.parameters||{};var n=Object(J.C)(t,e.parameters);(!n||n&&0===n.size)&&(e.parameters[t.get("name")]="")}}),e.contextUrl=L()(o.url()).toString(),h&&h.operationId?e.operationId=h.operationId:h&&s&&u&&(e.operationId=n.opId(h,s,u)),o.isOAS3()){var d="".concat(s,":").concat(u);e.server=a.selectedServer(d)||a.selectedServer();var m=a.serverVariables({server:e.server,namespace:d}).toJS(),g=a.serverVariables({server:e.server}).toJS();e.serverVariables=_()(m).length?m:g,e.requestContentType=a.requestContentType(s,u),e.responseContentType=a.responseContentType(s,u)||"*/*";var b=a.requestBodyValue(s,u);Object(J.t)(b)?e.requestBody=JSON.parse(b):b&&b.toJS?e.requestBody=b.toJS():e.requestBody=b}var w=y()({},e);w=n.buildRequest(w),r.setRequest(e.pathName,e.method,w);e.requestInterceptor=function(t){var n=p.apply(this,[t]),o=y()({},n);return r.setMutatedRequest(e.pathName,e.method,o),n},e.responseInterceptor=f;var x=v()();return n.execute(e).then(function(t){t.duration=v()()-x,r.setResponse(e.pathName,e.method,t)}).catch(function(t){console.error(t),r.setResponse(e.pathName,e.method,{error:!0,err:q()(t)})})}},Le=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.path,n=e.method,r=d()(e,["path","method"]);return function(e){var o=e.fn.fetch,i=e.specSelectors,a=e.specActions,s=i.specJsonWithResolvedSubtrees().toJS(),u=i.operationScheme(t,n),c=i.contentTypeValues([t,n]).toJS(),l=c.requestContentType,p=c.responseContentType,f=/xml/i.test(l),h=i.parameterValues([t,n],f).toJS();return a.executeRequest(Y({},r,{fetch:o,spec:s,pathName:t,method:n,parameters:h,requestContentType:l,scheme:u,responseContentType:p}))}};function Ue(e,t){return{type:ie,payload:{path:e,method:t}}}function qe(e,t){return{type:ae,payload:{path:e,method:t}}}function Fe(e,t,n){return{type:pe,payload:{scheme:e,path:t,method:n}}}},function(e,t,n){var r=n(32),o=n(22),i=n(63),a=n(77),s=n(75),u=function(e,t,n){var c,l,p,f=e&u.F,h=e&u.G,d=e&u.S,m=e&u.P,v=e&u.B,g=e&u.W,y=h?o:o[t]||(o[t]={}),b=y.prototype,_=h?r:d?r[t]:(r[t]||{}).prototype;for(c in h&&(n=t),n)(l=!f&&_&&void 0!==_[c])&&s(y,c)||(p=l?_[c]:n[c],y[c]=h&&"function"!=typeof _[c]?n[c]:v&&l?i(p,r):g&&_[c]==p?function(e){var t=function(t,n,r){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,r)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(p):m&&"function"==typeof p?i(Function.call,p):p,m&&((y.virtual||(y.virtual={}))[c]=p,e&u.R&&b&&!b[c]&&a(b,c,p)))};u.F=1,u.G=2,u.S=4,u.P=8,u.B=16,u.W=32,u.U=64,u.R=128,e.exports=u},function(e,t,n){"use strict";var r=n(138),o=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],i=["scalar","sequence","mapping"];e.exports=function(e,t){var n,a;if(t=t||{},Object.keys(t).forEach(function(t){if(-1===o.indexOf(t))throw new r('Unknown option "'+t+'" is met in definition of "'+e+'" YAML type.')}),this.tag=e,this.kind=t.kind||null,this.resolve=t.resolve||function(){return!0},this.construct=t.construct||function(e){return e},this.instanceOf=t.instanceOf||null,this.predicate=t.predicate||null,this.represent=t.represent||null,this.defaultStyle=t.defaultStyle||null,this.styleAliases=(n=t.styleAliases||null,a={},null!==n&&Object.keys(n).forEach(function(e){n[e].forEach(function(t){a[String(t)]=e})}),a),-1===i.indexOf(this.kind))throw new r('Unknown kind "'+this.kind+'" is specified for "'+e+'" YAML type.')}},function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(e,t,n){var r=n(197)("wks"),o=n(199),i=n(41).Symbol,a="function"==typeof i;(e.exports=function(e){return r[e]||(r[e]=a&&i[e]||(a?i:o)("Symbol."+e))}).store=r},function(e,t,n){var r=n(214)("wks"),o=n(159),i=n(32).Symbol,a="function"==typeof i;(e.exports=function(e){return r[e]||(r[e]=a&&i[e]||(a?i:o)("Symbol."+e))}).store=r},function(e,t,n){var r=n(41),o=n(72),i=n(81),a=n(97),s=n(153),u=function(e,t,n){var c,l,p,f,h=e&u.F,d=e&u.G,m=e&u.S,v=e&u.P,g=e&u.B,y=d?r:m?r[t]||(r[t]={}):(r[t]||{}).prototype,b=d?o:o[t]||(o[t]={}),_=b.prototype||(b.prototype={});for(c in d&&(n=t),n)p=((l=!h&&y&&void 0!==y[c])?y:n)[c],f=g&&l?s(p,r):v&&"function"==typeof p?s(Function.call,p):p,y&&a(y,c,p,e&u.U),b[c]!=p&&i(b,c,f),v&&_[c]!=p&&(_[c]=p)};r.core=o,u.F=1,u.G=2,u.S=4,u.P=8,u.B=16,u.W=32,u.U=64,u.R=128,e.exports=u},function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t){var n=Array.isArray;e.exports=n},function(e,t,n){"use strict";var r=!("undefined"==typeof window||!window.document||!window.document.createElement),o={canUseDOM:r,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:r&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:r&&!!window.screen,isInWorker:!r};e.exports=o},function(e,t,n){"use strict";var r=Object.prototype.hasOwnProperty;function o(e,t){return!!e&&r.call(e,t)}var i=/\\([\\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g;function a(e){return!(e>=55296&&e<=57343)&&(!(e>=64976&&e<=65007)&&(65535!=(65535&e)&&65534!=(65535&e)&&(!(e>=0&&e<=8)&&(11!==e&&(!(e>=14&&e<=31)&&(!(e>=127&&e<=159)&&!(e>1114111)))))))}function s(e){if(e>65535){var t=55296+((e-=65536)>>10),n=56320+(1023&e);return String.fromCharCode(t,n)}return String.fromCharCode(e)}var u=/&([a-z#][a-z0-9]{1,31});/gi,c=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i,l=n(463);function p(e,t){var n=0;return o(l,t)?l[t]:35===t.charCodeAt(0)&&c.test(t)&&a(n="x"===t[1].toLowerCase()?parseInt(t.slice(2),16):parseInt(t.slice(1),10))?s(n):e}var f=/[&<>"]/,h=/[&<>"]/g,d={"&":"&","<":"<",">":">",'"':"""};function m(e){return d[e]}t.assign=function(e){return[].slice.call(arguments,1).forEach(function(t){if(t){if("object"!=typeof t)throw new TypeError(t+"must be object");Object.keys(t).forEach(function(n){e[n]=t[n]})}}),e},t.isString=function(e){return"[object String]"===function(e){return Object.prototype.toString.call(e)}(e)},t.has=o,t.unescapeMd=function(e){return e.indexOf("\\")<0?e:e.replace(i,"$1")},t.isValidEntityCode=a,t.fromCodePoint=s,t.replaceEntities=function(e){return e.indexOf("&")<0?e:e.replace(u,p)},t.escapeHtml=function(e){return f.test(e)?e.replace(h,m):e}},function(e,t,n){var r=n(55),o=n(771);e.exports=function(e,t){if(null==e)return{};var n,i,a=o(e,t);if(r){var s=r(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}},function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(e,t,n){var r=n(35),o=n(99),i=n(73),a=/"/g,s=function(e,t,n,r){var o=String(i(e)),s="<"+t;return""!==n&&(s+=" "+n+'="'+String(r).replace(a,""")+'"'),s+">"+o+""};e.exports=function(e,t){var n={};n[e]=t(s),r(r.P+r.F*o(function(){var t=""[e]('"');return t!==t.toLowerCase()||t.split('"').length>3}),"String",n)}},function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,t,n){"use strict";n.r(t),n.d(t,"NEW_THROWN_ERR",function(){return i}),n.d(t,"NEW_THROWN_ERR_BATCH",function(){return a}),n.d(t,"NEW_SPEC_ERR",function(){return s}),n.d(t,"NEW_SPEC_ERR_BATCH",function(){return u}),n.d(t,"NEW_AUTH_ERR",function(){return c}),n.d(t,"CLEAR",function(){return l}),n.d(t,"CLEAR_BY",function(){return p}),n.d(t,"newThrownErr",function(){return f}),n.d(t,"newThrownErrBatch",function(){return h}),n.d(t,"newSpecErr",function(){return d}),n.d(t,"newSpecErrBatch",function(){return m}),n.d(t,"newAuthErr",function(){return v}),n.d(t,"clear",function(){return g}),n.d(t,"clearBy",function(){return y});var r=n(119),o=n.n(r),i="err_new_thrown_err",a="err_new_thrown_err_batch",s="err_new_spec_err",u="err_new_spec_err_batch",c="err_new_auth_err",l="err_clear",p="err_clear_by";function f(e){return{type:i,payload:o()(e)}}function h(e){return{type:a,payload:e}}function d(e){return{type:s,payload:e}}function m(e){return{type:u,payload:e}}function v(e){return{type:c,payload:e}}function g(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return{type:l,payload:e}}function y(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!0};return{type:p,payload:e}}},function(e,t,n){var r=n(98);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t,n){var r=n(43);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t){"function"==typeof Object.create?e.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:e.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},function(e,t,n){var r=n(64),o=r.Buffer;function i(e,t){for(var n in e)t[n]=e[n]}function a(e,t,n){return o(e,t,n)}o.from&&o.alloc&&o.allocUnsafe&&o.allocUnsafeSlow?e.exports=r:(i(r,t),t.Buffer=a),i(o,a),a.from=function(e,t,n){if("number"==typeof e)throw new TypeError("Argument must not be a number");return o(e,t,n)},a.alloc=function(e,t,n){if("number"!=typeof e)throw new TypeError("Argument must be a number");var r=o(e);return void 0!==t?"string"==typeof n?r.fill(t,n):r.fill(t):r.fill(0),r},a.allocUnsafe=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return o(e)},a.allocUnsafeSlow=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return r.SlowBuffer(e)}},function(e,t,n){var r=n(46),o=n(349),i=n(218),a=Object.defineProperty;t.f=n(50)?Object.defineProperty:function(e,t,n){if(r(e),t=i(t,!0),r(n),o)try{return a(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(e[t]=n.value),e}},function(e,t,n){e.exports=!n(82)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(e,t,n){var r=n(366),o="object"==typeof self&&self&&self.Object===Object&&self,i=r||o||Function("return this")();e.exports=i},function(e,t){e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},function(e,t,n){"use strict";e.exports={debugTool:null}},function(e,t,n){e.exports=n(573)},function(e,t,n){e.exports=n(770)},function(e,t,n){e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=45)}([function(e,t){e.exports=n(17)},function(e,t){e.exports=n(14)},function(e,t){e.exports=n(26)},function(e,t){e.exports=n(16)},function(e,t){e.exports=n(123)},function(e,t){e.exports=n(60)},function(e,t){e.exports=n(61)},function(e,t){e.exports=n(55)},function(e,t){e.exports=n(2)},function(e,t){e.exports=n(54)},function(e,t){e.exports=n(94)},function(e,t){e.exports=n(28)},function(e,t){e.exports=n(930)},function(e,t){e.exports=n(12)},function(e,t){e.exports=n(192)},function(e,t){e.exports=n(936)},function(e,t){e.exports=n(93)},function(e,t){e.exports=n(193)},function(e,t){e.exports=n(939)},function(e,t){e.exports=n(943)},function(e,t){e.exports=n(944)},function(e,t){e.exports=n(92)},function(e,t){e.exports=n(13)},function(e,t){e.exports=n(146)},function(e,t){e.exports=n(4)},function(e,t){e.exports=n(5)},function(e,t){e.exports=n(946)},function(e,t){e.exports=n(421)},function(e,t){e.exports=n(949)},function(e,t){e.exports=n(52)},function(e,t){e.exports=n(64)},function(e,t){e.exports=n(283)},function(e,t){e.exports=n(272)},function(e,t){e.exports=n(950)},function(e,t){e.exports=n(145)},function(e,t){e.exports=n(951)},function(e,t){e.exports=n(959)},function(e,t){e.exports=n(960)},function(e,t){e.exports=n(961)},function(e,t){e.exports=n(40)},function(e,t){e.exports=n(264)},function(e,t){e.exports=n(37)},function(e,t){e.exports=n(964)},function(e,t){e.exports=n(965)},function(e,t){e.exports=n(966)},function(e,t,n){e.exports=n(50)},function(e,t){e.exports=n(967)},function(e,t){e.exports=n(968)},function(e,t){e.exports=n(969)},function(e,t){e.exports=n(970)},function(e,t,n){"use strict";n.r(t);var r={};n.r(r),n.d(r,"path",function(){return mn}),n.d(r,"query",function(){return vn}),n.d(r,"header",function(){return yn}),n.d(r,"cookie",function(){return bn});var o=n(9),i=n.n(o),a=n(10),s=n.n(a),u=n(5),c=n.n(u),l=n(6),p=n.n(l),f=n(7),h=n.n(f),d=n(0),m=n.n(d),v=n(8),g=n.n(v),y=(n(46),n(15)),b=n.n(y),_=n(20),w=n.n(_),x=n(12),E=n.n(x),S=n(4),C=n.n(S),k=n(22),O=n.n(k),A=n(11),T=n.n(A),j=n(2),P=n.n(j),I=n(1),M=n.n(I),N=n(17),R=n.n(N),D=(n(47),n(26)),L=n.n(D),U=n(23),q=n.n(U),F=n(31),B=n.n(F),z={serializeRes:J,mergeInQueryOrForm:Z};function V(e){return H.apply(this,arguments)}function H(){return(H=R()(C.a.mark(function e(t){var n,r,o,i,a,s=arguments;return C.a.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(n=s.length>1&&void 0!==s[1]?s[1]:{},"object"===P()(t)&&(t=(n=t).url),n.headers=n.headers||{},z.mergeInQueryOrForm(n),n.headers&&m()(n.headers).forEach(function(e){var t=n.headers[e];"string"==typeof t&&(n.headers[e]=t.replace(/\n+/g," "))}),!n.requestInterceptor){e.next=12;break}return e.next=8,n.requestInterceptor(n);case 8:if(e.t0=e.sent,e.t0){e.next=11;break}e.t0=n;case 11:n=e.t0;case 12:return r=n.headers["content-type"]||n.headers["Content-Type"],/multipart\/form-data/i.test(r)&&(delete n.headers["content-type"],delete n.headers["Content-Type"]),e.prev=14,e.next=17,(n.userFetch||fetch)(n.url,n);case 17:return o=e.sent,e.next=20,z.serializeRes(o,t,n);case 20:if(o=e.sent,!n.responseInterceptor){e.next=28;break}return e.next=24,n.responseInterceptor(o);case 24:if(e.t1=e.sent,e.t1){e.next=27;break}e.t1=o;case 27:o=e.t1;case 28:e.next=38;break;case 30:if(e.prev=30,e.t2=e.catch(14),o){e.next=34;break}throw e.t2;case 34:throw(i=new Error(o.statusText)).statusCode=i.status=o.status,i.responseError=e.t2,i;case 38:if(o.ok){e.next=43;break}throw(a=new Error(o.statusText)).statusCode=a.status=o.status,a.response=o,a;case 43:return e.abrupt("return",o);case 44:case"end":return e.stop()}},e,null,[[14,30]])}))).apply(this,arguments)}var W=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return/(json|xml|yaml|text)\b/.test(e)};function J(e,t){var n=(arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).loadSpec,r=void 0!==n&&n,o={ok:e.ok,url:e.url||t,status:e.status,statusText:e.statusText,headers:K(e.headers)},i=o.headers["content-type"],a=r||W(i);return(a?e.text:e.blob||e.buffer).call(e).then(function(e){if(o.text=e,o.data=e,a)try{var t=function(e,t){return t&&(0===t.indexOf("application/json")||t.indexOf("+json")>0)?JSON.parse(e):q.a.safeLoad(e)}(e,i);o.body=t,o.obj=t}catch(e){o.parseError=e}return o})}function K(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t={};return"function"==typeof e.forEach?(e.forEach(function(e,n){void 0!==t[n]?(t[n]=M()(t[n])?t[n]:[t[n]],t[n].push(e)):t[n]=e}),t):t}function Y(e,t){return t||"undefined"==typeof navigator||(t=navigator),t&&"ReactNative"===t.product?!(!e||"object"!==P()(e)||"string"!=typeof e.uri):"undefined"!=typeof File?e instanceof File:null!==e&&"object"===P()(e)&&"function"==typeof e.pipe}function $(e,t){var n=e.collectionFormat,r=e.allowEmptyValue,o="object"===P()(e)?e.value:e;if(void 0===o&&r)return"";if(Y(o)||"boolean"==typeof o)return o;var i=encodeURIComponent;return t&&(i=B()(o)?function(e){return e}:function(e){return T()(e)}),"object"!==P()(o)||M()(o)?M()(o)?M()(o)&&!n?o.map(i).join(","):"multi"===n?o.map(i):o.map(i).join({csv:",",ssv:"%20",tsv:"%09",pipes:"|"}[n]):i(o):""}function G(e){var t=m()(e).reduce(function(t,n){var r,o=e[n],i=!!o.skipEncoding,a=i?n:encodeURIComponent(n),s=(r=o)&&"object"===P()(r)&&!M()(o);return t[a]=$(s?o:{value:o},i),t},{});return L.a.stringify(t,{encode:!1,indices:!1})||""}function Z(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.url,r=void 0===t?"":t,o=e.query,i=e.form;if(i){var a=m()(i).some(function(e){return Y(i[e].value)}),s=e.headers["content-type"]||e.headers["Content-Type"];if(a||/multipart\/form-data/i.test(s)){var u=n(48);e.body=new u,m()(i).forEach(function(t){e.body.append(t,$(i[t],!0))})}else e.body=G(i);delete e.form}if(o){var c=r.split("?"),l=O()(c,2),p=l[0],f=l[1],h="";if(f){var d=L.a.parse(f);m()(o).forEach(function(e){return delete d[e]}),h=L.a.stringify(d,{encode:!0})}var v=function(){for(var e=arguments.length,t=new Array(e),n=0;n0){var o=t(e,n[n.length-1],n);o&&(r=r.concat(o))}if(M()(e)){var i=e.map(function(e,r){return Ce(e,t,n.concat(r))});i&&(r=r.concat(i))}else if(Te(e)){var a=m()(e).map(function(r){return Ce(e[r],t,n.concat(r))});a&&(r=r.concat(a))}return r=Oe(r)}function ke(e){return M()(e)?e:[e]}function Oe(e){var t;return(t=[]).concat.apply(t,he()(e.map(function(e){return M()(e)?Oe(e):e})))}function Ae(e){return e.filter(function(e){return void 0!==e})}function Te(e){return e&&"object"===P()(e)}function je(e){return e&&"function"==typeof e}function Pe(e){if(Ne(e)){var t=e.op;return"add"===t||"remove"===t||"replace"===t}return!1}function Ie(e){return Pe(e)||Ne(e)&&"mutation"===e.type}function Me(e){return Ie(e)&&("add"===e.op||"replace"===e.op||"merge"===e.op||"mergeDeep"===e.op)}function Ne(e){return e&&"object"===P()(e)}function Re(e,t){try{return me.a.getValueByPointer(e,t)}catch(e){return console.error(e),{}}}var De=n(35),Le=n.n(De),Ue=n(36),qe=n(28),Fe=n.n(qe);function Be(e,t){function n(){Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack;for(var e=arguments.length,n=new Array(e),r=0;r-1&&-1===We.indexOf(n)||Je.indexOf(r)>-1||Ke.some(function(e){return r.indexOf(e)>-1})}function $e(e,t){var n=e.split("#"),r=O()(n,2),o=r[0],i=r[1],a=E.a.resolve(o||"",t||"");return i?"".concat(a,"#").concat(i):a}var Ge="application/json, application/yaml",Ze=new RegExp("^([a-z]+://|//)","i"),Xe=Be("JSONRefError",function(e,t,n){this.originalError=n,ie()(this,t||{})}),Qe={},et=new Le.a,tt=[function(e){return"paths"===e[0]&&"responses"===e[3]&&"content"===e[5]&&"example"===e[7]},function(e){return"paths"===e[0]&&"requestBody"===e[3]&&"content"===e[4]&&"example"===e[6]}],nt={key:"$ref",plugin:function(e,t,n,r){var o=r.getInstance(),i=n.slice(0,-1);if(!Ye(i)&&(a=i,!tt.some(function(e){return e(a)}))){var a,s=r.getContext(n).baseDoc;if("string"!=typeof e)return new Xe("$ref: must be a string (JSON-Ref)",{$ref:e,baseDoc:s,fullPath:n});var u,c,l,p=st(e),f=p[0],h=p[1]||"";try{u=s||f?it(f,s):null}catch(t){return at(t,{pointer:h,$ref:e,basePath:u,fullPath:n})}if(function(e,t,n,r){var o=et.get(r);o||(o={},et.set(r,o));var i=function(e){if(0===e.length)return"";return"/".concat(e.map(ht).join("/"))}(n),a="".concat(t||"","#").concat(e),s=i.replace(/allOf\/\d+\/?/g,""),u=r.contextTree.get([]).baseDoc;if(t==u&&mt(s,e))return!0;var c="";if(n.some(function(e){return c="".concat(c,"/").concat(ht(e)),o[c]&&o[c].some(function(e){return mt(e,a)||mt(a,e)})}))return!0;o[s]=(o[s]||[]).concat(a)}(h,u,i,r)&&!o.useCircularStructures){var d=$e(e,u);return e===d?null:_e.replace(n,d)}if(null==u?(l=pt(h),void 0===(c=r.get(l))&&(c=new Xe("Could not resolve reference: ".concat(e),{pointer:h,$ref:e,baseDoc:s,fullPath:n}))):c=null!=(c=ut(u,h)).__value?c.__value:c.catch(function(t){throw at(t,{pointer:h,$ref:e,baseDoc:s,fullPath:n})}),c instanceof Error)return[_e.remove(n),c];var v=$e(e,u),g=_e.replace(i,c,{$$ref:v});if(u&&u!==s)return[g,_e.context(i,{baseDoc:u})];try{if(!function(e,t){var n=[e];return t.path.reduce(function(e,t){return n.push(e[t]),e[t]},e),function e(t){return _e.isObject(t)&&(n.indexOf(t)>=0||m()(t).some(function(n){return e(t[n])}))}(t.value)}(r.state,g)||o.useCircularStructures)return g}catch(e){return null}}}},rt=ie()(nt,{docCache:Qe,absoluteify:it,clearCache:function(e){void 0!==e?delete Qe[e]:m()(Qe).forEach(function(e){delete Qe[e]})},JSONRefError:Xe,wrapError:at,getDoc:ct,split:st,extractFromDoc:ut,fetchJSON:function(e){return Object(Ue.fetch)(e,{headers:{Accept:Ge},loadSpec:!0}).then(function(e){return e.text()}).then(function(e){return q.a.safeLoad(e)})},extract:lt,jsonPointerToArray:pt,unescapeJsonPointerToken:ft}),ot=rt;function it(e,t){if(!Ze.test(e)){if(!t)throw new Xe("Tried to resolve a relative URL, without having a basePath. path: '".concat(e,"' basePath: '").concat(t,"'"));return E.a.resolve(t,e)}return e}function at(e,t){var n;return n=e&&e.response&&e.response.body?"".concat(e.response.body.code," ").concat(e.response.body.message):e.message,new Xe("Could not resolve reference: ".concat(n),t,e)}function st(e){return(e+"").split("#")}function ut(e,t){var n=Qe[e];if(n&&!_e.isPromise(n))try{var r=lt(t,n);return ie()(Q.a.resolve(r),{__value:r})}catch(e){return Q.a.reject(e)}return ct(e).then(function(e){return lt(t,e)})}function ct(e){var t=Qe[e];return t?_e.isPromise(t)?t:Q.a.resolve(t):(Qe[e]=rt.fetchJSON(e).then(function(t){return Qe[e]=t,t}),Qe[e])}function lt(e,t){var n=pt(e);if(n.length<1)return t;var r=_e.getIn(t,n);if(void 0===r)throw new Xe("Could not resolve pointer: ".concat(e," does not exist in document"),{pointer:e});return r}function pt(e){if("string"!=typeof e)throw new TypeError("Expected a string, got a ".concat(P()(e)));return"/"===e[0]&&(e=e.substr(1)),""===e?[]:e.split("/").map(ft)}function ft(e){return"string"!=typeof e?e:Fe.a.unescape(e.replace(/~1/g,"/").replace(/~0/g,"~"))}function ht(e){return Fe.a.escape(e.replace(/~/g,"~0").replace(/\//g,"~1"))}var dt=function(e){return!e||"/"===e||"#"===e};function mt(e,t){if(dt(t))return!0;var n=e.charAt(t.length),r=t.slice(-1);return 0===e.indexOf(t)&&(!n||"/"===n||"#"===n)&&"#"!==r}var vt={key:"allOf",plugin:function(e,t,n,r,o){if(!o.meta||!o.meta.$$ref){var i=n.slice(0,-1);if(!Ye(i)){if(!M()(e)){var a=new TypeError("allOf must be an array");return a.fullPath=n,a}var s=!1,u=o.value;i.forEach(function(e){u&&(u=u[e])}),delete(u=ie()({},u)).allOf;var c=[];return c.push(r.replace(i,{})),e.forEach(function(e,t){if(!r.isObject(e)){if(s)return null;s=!0;var o=new TypeError("Elements in allOf must be objects");return o.fullPath=n,c.push(o)}c.push(r.mergeDeep(i,e));var a=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.specmap,o=n.getBaseUrlForNodePath,i=void 0===o?function(e){return r.getContext([].concat(he()(t),he()(e))).baseDoc}:o,a=n.targetKeys,s=void 0===a?["$ref","$$ref"]:a,u=[];return Ve()(e).forEach(function(){if(s.indexOf(this.key)>-1){var e=this.path,n=t.concat(this.path),o=$e(this.node,i(e));u.push(r.replace(n,o))}}),u}(e,n.slice(0,-1),{getBaseUrlForNodePath:function(e){return r.getContext([].concat(he()(n),[t],he()(e))).baseDoc},specmap:r});c.push.apply(c,he()(a))}),c.push(r.mergeDeep(i,u)),u.$$ref||c.push(r.remove([].concat(i,"$$ref"))),c}}}},gt={key:"parameters",plugin:function(e,t,n,r,o){if(M()(e)&&e.length){var i=ie()([],e),a=n.slice(0,-1),s=ie()({},_e.getIn(r.spec,a));return e.forEach(function(e,t){try{i[t].default=r.parameterMacro(s,e)}catch(e){var o=new Error(e);return o.fullPath=n,o}}),_e.replace(n,i)}return _e.replace(n,e)}},yt={key:"properties",plugin:function(e,t,n,r){var o=ie()({},e);for(var i in e)try{o[i].default=r.modelPropertyMacro(o[i])}catch(e){var a=new Error(e);return a.fullPath=n,a}return _e.replace(n,o)}};function bt(e,t){var n=m()(e);if(h.a){var r=h()(e);t&&(r=r.filter(function(t){return p()(e,t).enumerable})),n.push.apply(n,r)}return n}var _t=function(){function e(t){se()(this,e),this.root=wt(t||{})}return ce()(e,[{key:"set",value:function(e,t){var n=this.getParent(e,!0);if(n){var r=e[e.length-1],o=n.children;o[r]?xt(o[r],t,n):o[r]=wt(t,n)}else xt(this.root,t,null)}},{key:"get",value:function(e){if((e=e||[]).length<1)return this.root.value;for(var t,n,r=this.root,o=0;o1?n-1:0),o=1;o1?n-1:0),o=1;o0})}},{key:"nextPromisedPatch",value:function(){if(this.promisedPatches.length>0)return Q.a.race(this.promisedPatches.map(function(e){return e.value}))}},{key:"getPluginHistory",value:function(e){var t=this.getPluginName(e);return this.pluginHistory[t]||[]}},{key:"getPluginRunCount",value:function(e){return this.getPluginHistory(e).length}},{key:"getPluginHistoryTip",value:function(e){var t=this.getPluginHistory(e);return t&&t[t.length-1]||{}}},{key:"getPluginMutationIndex",value:function(e){var t=this.getPluginHistoryTip(e).mutationIndex;return"number"!=typeof t?-1:t}},{key:"getPluginName",value:function(e){return e.pluginName}},{key:"updatePluginHistory",value:function(e,t){var n=this.getPluginName(e);(this.pluginHistory[n]=this.pluginHistory[n]||[]).push(t)}},{key:"updatePatches",value:function(e,t){var n=this;_e.normalizeArray(e).forEach(function(e){if(e instanceof Error)n.errors.push(e);else try{if(!_e.isObject(e))return void n.debug("updatePatches","Got a non-object patch",e);if(n.showDebug&&n.allPatches.push(e),_e.isPromise(e.value))return n.promisedPatches.push(e),void n.promisedPatchThen(e);if(_e.isContextPatch(e))return void n.setContext(e.path,e.value);if(_e.isMutation(e))return void n.updateMutations(e)}catch(e){console.error(e),n.errors.push(e)}})}},{key:"updateMutations",value:function(e){"object"===P()(e.value)&&!M()(e.value)&&this.allowMetaPatches&&(e.value=ie()({},e.value));var t=_e.applyPatch(this.state,e,{allowMetaPatches:this.allowMetaPatches});t&&(this.mutations.push(e),this.state=t)}},{key:"removePromisedPatch",value:function(e){var t=this.promisedPatches.indexOf(e);t<0?this.debug("Tried to remove a promisedPatch that isn't there!"):this.promisedPatches.splice(t,1)}},{key:"promisedPatchThen",value:function(e){var t=this;return e.value=e.value.then(function(n){var r=ie()({},e,{value:n});t.removePromisedPatch(e),t.updatePatches(r)}).catch(function(n){t.removePromisedPatch(e),t.updatePatches(n)})}},{key:"getMutations",value:function(e,t){return e=e||0,"number"!=typeof t&&(t=this.mutations.length),this.mutations.slice(e,t)}},{key:"getCurrentMutations",value:function(){return this.getMutationsForPlugin(this.getCurrentPlugin())}},{key:"getMutationsForPlugin",value:function(e){var t=this.getPluginMutationIndex(e);return this.getMutations(t+1)}},{key:"getCurrentPlugin",value:function(){return this.currentPlugin}},{key:"getPatchesOfType",value:function(e,t){return e.filter(t)}},{key:"getLib",value:function(){return this.libMethods}},{key:"_get",value:function(e){return _e.getIn(this.state,e)}},{key:"_getContext",value:function(e){return this.contextTree.get(e)}},{key:"setContext",value:function(e,t){return this.contextTree.set(e,t)}},{key:"_hasRun",value:function(e){return this.getPluginRunCount(this.getCurrentPlugin())>(e||0)}},{key:"_clone",value:function(e){return JSON.parse(T()(e))}},{key:"dispatch",value:function(){var e=this,t=this,n=this.nextPlugin();if(!n){var r=this.nextPromisedPatch();if(r)return r.then(function(){return e.dispatch()}).catch(function(){return e.dispatch()});var o={spec:this.state,errors:this.errors};return this.showDebug&&(o.patches=this.allPatches),Q.a.resolve(o)}if(t.pluginCount=t.pluginCount||{},t.pluginCount[n]=(t.pluginCount[n]||0)+1,t.pluginCount[n]>100)return Q.a.resolve({spec:t.state,errors:t.errors.concat(new Error("We've reached a hard limit of ".concat(100," plugin runs")))});if(n!==this.currentPlugin&&this.promisedPatches.length){var i=this.promisedPatches.map(function(e){return e.value});return Q.a.all(i.map(function(e){return e.then(Function,Function)})).then(function(){return e.dispatch()})}return function(){t.currentPlugin=n;var e=t.getCurrentMutations(),r=t.mutations.length-1;try{if(n.isGenerator){var o=!0,i=!1,s=void 0;try{for(var u,c=te()(n(e,t.getLib()));!(o=(u=c.next()).done);o=!0){a(u.value)}}catch(e){i=!0,s=e}finally{try{o||null==c.return||c.return()}finally{if(i)throw s}}}else{a(n(e,t.getLib()))}}catch(e){console.error(e),a([ie()(re()(e),{plugin:n})])}finally{t.updatePluginHistory(n,{mutationIndex:r})}return t.dispatch()}();function a(e){e&&(e=_e.fullyNormalizeArray(e),t.updatePatches(e,n))}}}]),e}();var St={refs:ot,allOf:vt,parameters:gt,properties:yt},Ct=n(29),kt=n.n(Ct),Ot=function(e){return String.prototype.toLowerCase.call(e)},At=function(e){return e.replace(/[^\w]/gi,"_")};function Tt(e){var t=e.openapi;return!!t&&w()(t,"3")}function jt(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",r=(arguments.length>3&&void 0!==arguments[3]?arguments[3]:{}).v2OperationIdCompatibilityMode;return e&&"object"===P()(e)?(e.operationId||"").replace(/\s/g,"").length?At(e.operationId):function(e,t){if((arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).v2OperationIdCompatibilityMode){var n="".concat(t.toLowerCase(),"_").concat(e).replace(/[\s!@#$%^&*()_+=[{\]};:<>|.\/?,\\'""-]/g,"_");return(n=n||"".concat(e.substring(1),"_").concat(t)).replace(/((_){2,})/g,"_").replace(/^(_)*/g,"").replace(/([_])*$/g,"")}return"".concat(Ot(t)).concat(At(e))}(t,n,{v2OperationIdCompatibilityMode:r}):null}function Pt(e,t){return"".concat(Ot(t),"-").concat(e)}function It(e,t){return e&&e.paths?function(e,t){return Mt(e,t,!0)||null}(e,function(e){var n=e.pathName,r=e.method,o=e.operation;if(!o||"object"!==P()(o))return!1;var i=o.operationId;return[jt(o,n,r),Pt(n,r),i].some(function(e){return e&&e===t})}):null}function Mt(e,t,n){if(!e||"object"!==P()(e)||!e.paths||"object"!==P()(e.paths))return null;var r=e.paths;for(var o in r)for(var i in r[o])if("PARAMETERS"!==i.toUpperCase()){var a=r[o][i];if(a&&"object"===P()(a)){var s={spec:e,pathName:o,method:i.toUpperCase(),operation:a},u=t(s);if(n&&u)return s}}}function Nt(e){var t=e.spec,n=t.paths,r={};if(!n||t.$$normalized)return e;for(var o in n){var i=n[o];if(kt()(i)){var a=i.parameters,s=function(e){var n=i[e];if(!kt()(n))return"continue";var s=jt(n,o,e);if(s){r[s]?r[s].push(n):r[s]=[n];var u=r[s];if(u.length>1)u.forEach(function(e,t){e.__originalOperationId=e.__originalOperationId||e.operationId,e.operationId="".concat(s).concat(t+1)});else if(void 0!==n.operationId){var c=u[0];c.__originalOperationId=c.__originalOperationId||n.operationId,c.operationId=s}}if("parameters"!==e){var l=[],p={};for(var f in t)"produces"!==f&&"consumes"!==f&&"security"!==f||(p[f]=t[f],l.push(p));if(a&&(p.parameters=a,l.push(p)),l.length)for(var h=0,d=l;h1&&void 0!==arguments[1]?arguments[1]:{},n=t.requestInterceptor,r=t.responseInterceptor,o=e.withCredentials?"include":"same-origin";return function(t){return e({url:t,loadSpec:!0,requestInterceptor:n,responseInterceptor:r,headers:{Accept:Ge},credentials:o}).then(function(e){return e.body})}}function Dt(e){var t=e.fetch,n=e.spec,r=e.url,o=e.mode,i=e.allowMetaPatches,a=void 0===i||i,s=e.pathDiscriminator,u=e.modelPropertyMacro,c=e.parameterMacro,l=e.requestInterceptor,p=e.responseInterceptor,f=e.skipNormalization,h=e.useCircularStructures,d=e.http,m=e.baseDoc;return m=m||r,d=t||d||V,n?v(n):Rt(d,{requestInterceptor:l,responseInterceptor:p})(m).then(v);function v(e){m&&(St.refs.docCache[m]=e),St.refs.fetchJSON=Rt(d,{requestInterceptor:l,responseInterceptor:p});var t,n=[St.refs];return"function"==typeof c&&n.push(St.parameters),"function"==typeof u&&n.push(St.properties),"strict"!==o&&n.push(St.allOf),(t={spec:e,context:{baseDoc:m},plugins:n,allowMetaPatches:a,pathDiscriminator:s,parameterMacro:c,modelPropertyMacro:u,useCircularStructures:h},new Et(t).dispatch()).then(f?function(){var e=R()(C.a.mark(function e(t){return C.a.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",t);case 1:case"end":return e.stop()}},e)}));return function(t){return e.apply(this,arguments)}}():Nt)}}var Lt=n(16),Ut=n.n(Lt);function qt(e,t){var n=m()(e);if(h.a){var r=h()(e);t&&(r=r.filter(function(t){return p()(e,t).enumerable})),n.push.apply(n,r)}return n}function Ft(e){for(var t=1;t2&&void 0!==m[2]?m[2]:{},o=r.returnEntireTree,i=r.baseDoc,a=r.requestInterceptor,s=r.responseInterceptor,u=r.parameterMacro,c=r.modelPropertyMacro,l=r.useCircularStructures,p={pathDiscriminator:n,baseDoc:i,requestInterceptor:a,responseInterceptor:s,parameterMacro:u,modelPropertyMacro:c,useCircularStructures:l},f=Nt({spec:t}),h=f.spec,e.next=6,Dt(Ft({},p,{spec:h,allowMetaPatches:!0,skipNormalization:!0}));case 6:return d=e.sent,!o&&M()(n)&&n.length&&(d.spec=Ut()(d.spec,n)||null),e.abrupt("return",d);case 9:case"end":return e.stop()}},e)}))).apply(this,arguments)}var zt=n(38),Vt=n.n(zt);function Ht(e,t){var n=m()(e);if(h.a){var r=h()(e);t&&(r=r.filter(function(t){return p()(e,t).enumerable})),n.push.apply(n,r)}return n}function Wt(e){for(var t=1;t0&&void 0!==arguments[0]?arguments[0]:{};return function(t){var n=t.pathName,r=t.method,o=t.operationId;return function(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.execute(Wt({spec:e.spec},Vt()(e,"requestInterceptor","responseInterceptor","userFetch"),{pathName:n,method:r,parameters:t,operationId:o},i))}}}};var $t=n(39),Gt=n.n($t),Zt=n(40),Xt=n.n(Zt),Qt=n(41),en=n.n(Qt),tn=n(19),nn=n.n(tn),rn=n(42),on=n.n(rn),an={body:function(e){var t=e.req,n=e.value;t.body=n},header:function(e){var t=e.req,n=e.parameter,r=e.value;t.headers=t.headers||{},void 0!==r&&(t.headers[n.name]=r)},query:function(e){var t=e.req,n=e.value,r=e.parameter;t.query=t.query||{},!1===n&&"boolean"===r.type&&(n="false");0===n&&["number","integer"].indexOf(r.type)>-1&&(n="0");if(n)t.query[r.name]={collectionFormat:r.collectionFormat,value:n};else if(r.allowEmptyValue&&void 0!==n){var o=r.name;t.query[o]=t.query[o]||{},t.query[o].allowEmptyValue=!0}},path:function(e){var t=e.req,n=e.value,r=e.parameter;t.url=t.url.split("{".concat(r.name,"}")).join(encodeURIComponent(n))},formData:function(e){var t=e.req,n=e.value,r=e.parameter;(n||r.allowEmptyValue)&&(t.form=t.form||{},t.form[r.name]={value:n,allowEmptyValue:r.allowEmptyValue,collectionFormat:r.collectionFormat})}};n(49);var sn=n(43),un=n.n(sn),cn=n(44),ln=function(e){return":/?#[]@!$&'()*+,;=".indexOf(e)>-1},pn=function(e){return/^[a-z0-9\-._~]+$/i.test(e)};function fn(e){var t=(arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}).escape,n=arguments.length>2?arguments[2]:void 0;return"number"==typeof e&&(e=e.toString()),"string"==typeof e&&e.length&&t?n?JSON.parse(e):Object(cn.stringToCharArray)(e).map(function(e){return pn(e)?e:ln(e)&&"unsafe"===t?e:(un()(e)||[]).map(function(e){return"0".concat(e.toString(16).toUpperCase()).slice(-2)}).map(function(e){return"%".concat(e)}).join("")}).join(""):e}function hn(e){var t=e.value;return M()(t)?function(e){var t=e.key,n=e.value,r=e.style,o=e.explode,i=e.escape,a=function(e){return fn(e,{escape:i})};if("simple"===r)return n.map(function(e){return a(e)}).join(",");if("label"===r)return".".concat(n.map(function(e){return a(e)}).join("."));if("matrix"===r)return n.map(function(e){return a(e)}).reduce(function(e,n){return!e||o?"".concat(e||"",";").concat(t,"=").concat(n):"".concat(e,",").concat(n)},"");if("form"===r){var s=o?"&".concat(t,"="):",";return n.map(function(e){return a(e)}).join(s)}if("spaceDelimited"===r){var u=o?"".concat(t,"="):"";return n.map(function(e){return a(e)}).join(" ".concat(u))}if("pipeDelimited"===r){var c=o?"".concat(t,"="):"";return n.map(function(e){return a(e)}).join("|".concat(c))}}(e):"object"===P()(t)?function(e){var t=e.key,n=e.value,r=e.style,o=e.explode,i=e.escape,a=function(e){return fn(e,{escape:i})},s=m()(n);if("simple"===r)return s.reduce(function(e,t){var r=a(n[t]),i=o?"=":",",s=e?"".concat(e,","):"";return"".concat(s).concat(t).concat(i).concat(r)},"");if("label"===r)return s.reduce(function(e,t){var r=a(n[t]),i=o?"=":".",s=e?"".concat(e,"."):".";return"".concat(s).concat(t).concat(i).concat(r)},"");if("matrix"===r&&o)return s.reduce(function(e,t){var r=a(n[t]),o=e?"".concat(e,";"):";";return"".concat(o).concat(t,"=").concat(r)},"");if("matrix"===r)return s.reduce(function(e,r){var o=a(n[r]),i=e?"".concat(e,","):";".concat(t,"=");return"".concat(i).concat(r,",").concat(o)},"");if("form"===r)return s.reduce(function(e,t){var r=a(n[t]),i=e?"".concat(e).concat(o?"&":","):"",s=o?"=":",";return"".concat(i).concat(t).concat(s).concat(r)},"")}(e):function(e){var t=e.key,n=e.value,r=e.style,o=e.escape,i=function(e){return fn(e,{escape:o})};if("simple"===r)return i(n);if("label"===r)return".".concat(i(n));if("matrix"===r)return";".concat(t,"=").concat(i(n));if("form"===r)return i(n);if("deepObject"===r)return i(n)}(e)}function dn(e,t){return t.includes("application/json")?"string"==typeof e?e:T()(e):e.toString()}function mn(e){var t=e.req,n=e.value,r=e.parameter,o=r.name,i=r.style,a=r.explode,s=r.content;if(s){var u=m()(s)[0];t.url=t.url.split("{".concat(o,"}")).join(fn(dn(n,u),{escape:!0}))}else{var c=hn({key:r.name,value:n,style:i||"simple",explode:a||!1,escape:!0});t.url=t.url.split("{".concat(o,"}")).join(c)}}function vn(e){var t=e.req,n=e.value,r=e.parameter;if(t.query=t.query||{},r.content){var o=m()(r.content)[0];t.query[r.name]=dn(n,o)}else if(!1===n&&(n="false"),0===n&&(n="0"),n){var i=P()(n);if("deepObject"===r.style)m()(n).forEach(function(e){var o=n[e];t.query["".concat(r.name,"[").concat(e,"]")]={value:hn({key:e,value:o,style:"deepObject",escape:r.allowReserved?"unsafe":"reserved"}),skipEncoding:!0}});else if("object"!==i||M()(n)||"form"!==r.style&&r.style||!r.explode&&void 0!==r.explode){var a=encodeURIComponent(r.name);t.query[a]={value:hn({key:a,value:n,style:r.style||"form",explode:void 0===r.explode||r.explode,escape:r.allowReserved?"unsafe":"reserved"}),skipEncoding:!0}}else{m()(n).forEach(function(e){var o=n[e];t.query[e]={value:hn({key:e,value:o,style:r.style||"form",escape:r.allowReserved?"unsafe":"reserved"}),skipEncoding:!0}})}}else if(r.allowEmptyValue&&void 0!==n){var s=r.name;t.query[s]=t.query[s]||{},t.query[s].allowEmptyValue=!0}}var gn=["accept","authorization","content-type"];function yn(e){var t=e.req,n=e.parameter,r=e.value;if(t.headers=t.headers||{},!(gn.indexOf(n.name.toLowerCase())>-1))if(n.content){var o=m()(n.content)[0];t.headers[n.name]=dn(r,o)}else void 0!==r&&(t.headers[n.name]=hn({key:n.name,value:r,style:n.style||"simple",explode:void 0!==n.explode&&n.explode,escape:!1}))}function bn(e){var t=e.req,n=e.parameter,r=e.value;t.headers=t.headers||{};var o=P()(r);if(n.content){var i=m()(n.content)[0];t.headers.Cookie="".concat(n.name,"=").concat(dn(r,i))}else if("undefined"!==o){var a="object"===o&&!M()(r)&&n.explode?"":"".concat(n.name,"=");t.headers.Cookie=a+hn({key:n.name,value:r,escape:!1,style:n.style||"form",explode:void 0!==n.explode&&n.explode})}}var _n=n(30),wn=function(e,t){var n=e.operation,r=e.requestBody,o=e.securities,i=e.spec,a=e.attachContentTypeForEmptyPayload,s=e.requestContentType;t=function(e){var t=e.request,n=e.securities,r=void 0===n?{}:n,o=e.operation,i=void 0===o?{}:o,a=e.spec,s=b()({},t),u=r.authorized,c=void 0===u?{}:u,l=i.security||a.security||[],p=c&&!!m()(c).length,f=Ut()(a,["components","securitySchemes"])||{};if(s.headers=s.headers||{},s.query=s.query||{},!m()(r).length||!p||!l||M()(i.security)&&!i.security.length)return t;return l.forEach(function(e,t){for(var n in e){var r=c[n],o=f[n];if(r){var i=r.value||r,a=o.type;if(r)if("apiKey"===a)"query"===o.in&&(s.query[o.name]=i),"header"===o.in&&(s.headers[o.name]=i),"cookie"===o.in&&(s.cookies[o.name]=i);else if("http"===a){if("basic"===o.scheme){var u=i.username,l=i.password,p=nn()("".concat(u,":").concat(l));s.headers.Authorization="Basic ".concat(p)}"bearer"===o.scheme&&(s.headers.Authorization="Bearer ".concat(i))}else if("oauth2"===a){var h=r.token||{},d=h[o["x-tokenName"]||"access_token"],m=h.token_type;m&&"bearer"!==m.toLowerCase()||(m="Bearer"),s.headers.Authorization="".concat(m," ").concat(d)}}}}),s}({request:t,securities:o,operation:n,spec:i});var u=n.requestBody||{},c=m()(u.content||{}),l=s&&c.indexOf(s)>-1;if(r||a){if(s&&l)t.headers["Content-Type"]=s;else if(!s){var p=c[0];p&&(t.headers["Content-Type"]=p,s=p)}}else s&&l&&(t.headers["Content-Type"]=s);return r&&(s?c.indexOf(s)>-1&&("application/x-www-form-urlencoded"===s||0===s.indexOf("multipart/")?"object"===P()(r)?(t.form={},m()(r).forEach(function(e){var n,o,i=r[e];"undefined"!=typeof File&&(o=i instanceof File),"undefined"!=typeof Blob&&(o=o||i instanceof Blob),void 0!==_n.Buffer&&(o=o||_n.Buffer.isBuffer(i)),n="object"!==P()(i)||o?i:M()(i)?i.toString():T()(i),t.form[e]={value:n}})):t.form=r:t.body=r):t.body=r),t};var xn=function(e,t){var n=e.spec,r=e.operation,o=e.securities,i=e.requestContentType,a=e.attachContentTypeForEmptyPayload;if((t=function(e){var t=e.request,n=e.securities,r=void 0===n?{}:n,o=e.operation,i=void 0===o?{}:o,a=e.spec,s=b()({},t),u=r.authorized,c=void 0===u?{}:u,l=r.specSecurity,p=void 0===l?[]:l,f=i.security||p,h=c&&!!m()(c).length,d=a.securityDefinitions;if(s.headers=s.headers||{},s.query=s.query||{},!m()(r).length||!h||!f||M()(i.security)&&!i.security.length)return t;return f.forEach(function(e,t){for(var n in e){var r=c[n];if(r){var o=r.token,i=r.value||r,a=d[n],u=a.type,l=a["x-tokenName"]||"access_token",p=o&&o[l],f=o&&o.token_type;if(r)if("apiKey"===u){var h="query"===a.in?"query":"headers";s[h]=s[h]||{},s[h][a.name]=i}else"basic"===u?i.header?s.headers.authorization=i.header:(i.base64=nn()("".concat(i.username,":").concat(i.password)),s.headers.authorization="Basic ".concat(i.base64)):"oauth2"===u&&p&&(f=f&&"bearer"!==f.toLowerCase()?f:"Bearer",s.headers.authorization="".concat(f," ").concat(p))}}}),s}({request:t,securities:o,operation:r,spec:n})).body||t.form||a)i?t.headers["Content-Type"]=i:M()(r.consumes)?t.headers["Content-Type"]=r.consumes[0]:M()(n.consumes)?t.headers["Content-Type"]=n.consumes[0]:r.parameters&&r.parameters.filter(function(e){return"file"===e.type}).length?t.headers["Content-Type"]="multipart/form-data":r.parameters&&r.parameters.filter(function(e){return"formData"===e.in}).length&&(t.headers["Content-Type"]="application/x-www-form-urlencoded");else if(i){var s=r.parameters&&r.parameters.filter(function(e){return"body"===e.in}).length>0,u=r.parameters&&r.parameters.filter(function(e){return"formData"===e.in}).length>0;(s||u)&&(t.headers["Content-Type"]=i)}return t};function En(e,t){var n=m()(e);if(h.a){var r=h()(e);t&&(r=r.filter(function(t){return p()(e,t).enumerable})),n.push.apply(n,r)}return n}function Sn(e){for(var t=1;t-1&&(c=o,l=u[p.indexOf(o)])}return!c&&u&&u.length&&(c=u[0].url,l=u[0]),c.indexOf("{")>-1&&function(e){for(var t,n=[],r=/{([^}]+)}/g;t=r.exec(e);)n.push(t[1]);return n}(c).forEach(function(e){if(l.variables&&l.variables[e]){var t=l.variables[e],n=s[e]||t.default,r=new RegExp("{".concat(e,"}"),"g");c=c.replace(r,n)}}),function(){var e,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",r=E.a.parse(t),o=E.a.parse(n),i=Pn(r.protocol)||Pn(o.protocol)||"",a=r.host||o.host,s=r.pathname||"";return"/"===(e=i&&a?"".concat(i,"://").concat(a+s):s)[e.length-1]?e.slice(0,-1):e}(c,i)}(b):function(e){var t,n=e.spec,r=e.scheme,o=e.contextUrl,i=void 0===o?"":o,a=E.a.parse(i),s=M()(n.schemes)?n.schemes[0]:null,u=r||s||Pn(a.protocol)||"http",c=n.host||a.host||"",l=n.basePath||"";return"/"===(t=u&&c?"".concat(u,"://").concat(c+l):l)[t.length-1]?t.slice(0,-1):t}(b),!n)return delete g.cookies,g;g.url+=S,g.method="".concat(x).toUpperCase(),h=h||{};var C=t.paths[S]||{};o&&(g.headers.accept=o);var k=An([].concat(Cn(w.parameters)).concat(Cn(C.parameters)));k.forEach(function(e){var n,r=d[e.in];if("body"===e.in&&e.schema&&e.schema.properties&&(n=h),void 0===(n=e&&e.name&&h[e.name])?n=e&&e.name&&h["".concat(e.in,".").concat(e.name)]:On(e.name,k).length>1&&console.warn("Parameter '".concat(e.name,"' is ambiguous because the defined spec has more than one parameter with the name: '").concat(e.name,"' and the passed-in parameter values did not define an 'in' value.")),null!==n){if(void 0!==e.default&&void 0===n&&(n=e.default),void 0===n&&e.required&&!e.allowEmptyValue)throw new Error("Required parameter ".concat(e.name," is not provided"));if(v&&e.schema&&"object"===e.schema.type&&"string"==typeof n)try{n=JSON.parse(n)}catch(e){throw new Error("Could not parse object parameter value string as JSON")}r&&r({req:g,parameter:e,value:n,operation:w,spec:t})}});var O=Sn({},e,{operation:w});if((g=v?wn(O,g):xn(O,g)).cookies&&m()(g.cookies).length){var A=m()(g.cookies).reduce(function(e,t){var n=g.cookies[t];return e+(e?"&":"")+on.a.serialize(t,n)},"");g.headers.Cookie=A}return g.cookies&&delete g.cookies,Z(g),g}var Pn=function(e){return e?e.replace(/\W/g,""):null};function In(e,t){var n=m()(e);if(h.a){var r=h()(e);t&&(r=r.filter(function(t){return p()(e,t).enumerable})),n.push.apply(n,r)}return n}function Mn(e){var t=this,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("string"==typeof e?n.url=e:n=e,!(this instanceof Mn))return new Mn(n);b()(this,n);var r=this.resolve().then(function(){return t.disableInterfaces||b()(t,Mn.makeApisTagOperation(t)),t});return r.client=this,r}Mn.http=V,Mn.makeHttp=function(e,t,n){return n=n||function(e){return e},t=t||function(e){return e},function(r){return"string"==typeof r&&(r={url:r}),z.mergeInQueryOrForm(r),r=t(r),n(e(r))}}.bind(null,Mn.http),Mn.resolve=Dt,Mn.resolveSubtree=function(e,t){return Bt.apply(this,arguments)},Mn.execute=function(e){var t=e.http,n=e.fetch,r=e.spec,o=e.operationId,i=e.pathName,a=e.method,s=e.parameters,u=e.securities,c=Gt()(e,["http","fetch","spec","operationId","pathName","method","parameters","securities"]),l=t||n||V;i&&a&&!o&&(o=Pt(i,a));var p=Tn.buildRequest(Sn({spec:r,operationId:o,parameters:s,securities:u,http:l},c));return p.body&&(Xt()(p.body)||en()(p.body))&&(p.body=T()(p.body)),l(p)},Mn.serializeRes=J,Mn.serializeHeaders=K,Mn.clearCache=function(){St.refs.clearCache()},Mn.makeApisTagOperation=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=Yt.makeExecute(e);return{apis:Yt.mapTagOperations({v2OperationIdCompatibilityMode:e.v2OperationIdCompatibilityMode,spec:e.spec,cb:t})}},Mn.buildRequest=jn,Mn.helpers={opId:jt},Mn.prototype={http:V,execute:function(e){return this.applyDefaults(),Mn.execute(function(e){for(var t=1;t + * @license MIT + */ +var r=n(569),o=n(570),i=n(355);function a(){return u.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(a()=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function d(e,t){if(u.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return B(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return z(e).length;default:if(r)return B(e).length;t=(""+t).toLowerCase(),r=!0}}function m(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return j(this,t,n);case"utf8":case"utf-8":return k(this,t,n);case"ascii":return A(this,t,n);case"latin1":case"binary":return T(this,t,n);case"base64":return C(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return P(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function v(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function g(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=u.from(t,r)),u.isBuffer(t))return 0===t.length?-1:y(e,t,n,r,o);if("number"==typeof t)return t&=255,u.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):y(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function y(e,t,n,r,o){var i,a=1,s=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,u/=2,n/=2}function c(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var l=-1;for(i=n;is&&(n=s-u),i=n;i>=0;i--){for(var p=!0,f=0;fo&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var a=0;a>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function C(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function k(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:c>223?3:c>191?2:1;if(o+p<=n)switch(p){case 1:c<128&&(l=c);break;case 2:128==(192&(i=e[o+1]))&&(u=(31&c)<<6|63&i)>127&&(l=u);break;case 3:i=e[o+1],a=e[o+2],128==(192&i)&&128==(192&a)&&(u=(15&c)<<12|(63&i)<<6|63&a)>2047&&(u<55296||u>57343)&&(l=u);break;case 4:i=e[o+1],a=e[o+2],s=e[o+3],128==(192&i)&&128==(192&a)&&128==(192&s)&&(u=(15&c)<<18|(63&i)<<12|(63&a)<<6|63&s)>65535&&u<1114112&&(l=u)}null===l?(l=65533,p=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=p}return function(e){var t=e.length;if(t<=O)return String.fromCharCode.apply(String,e);var n="",r=0;for(;r0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},u.prototype.compare=function(e,t,n,r,o){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),a=(n>>>=0)-(t>>>=0),s=Math.min(i,a),c=this.slice(r,o),l=e.slice(t,n),p=0;po)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return _(this,e,t,n);case"ascii":return w(this,e,t,n);case"latin1":case"binary":return x(this,e,t,n);case"base64":return E(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var O=4096;function A(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;or)&&(n=r);for(var o="",i=t;in)throw new RangeError("Trying to access beyond buffer length")}function M(e,t,n,r,o,i){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function N(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function R(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function D(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function L(e,t,n,r,i){return i||D(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function U(e,t,n,r,i){return i||D(e,0,n,8),o.write(e,t,n,r,52,8),n+8}u.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(o*=256);)r+=this[e+--t]*o;return r},u.prototype.readUInt8=function(e,t){return t||I(e,1,this.length),this[e]},u.prototype.readUInt16LE=function(e,t){return t||I(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUInt16BE=function(e,t){return t||I(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUInt32LE=function(e,t){return t||I(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUInt32BE=function(e,t){return t||I(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||I(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},u.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||I(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},u.prototype.readInt8=function(e,t){return t||I(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){t||I(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(e,t){t||I(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(e,t){return t||I(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return t||I(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readFloatLE=function(e,t){return t||I(e,4,this.length),o.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return t||I(e,4,this.length),o.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return t||I(e,8,this.length),o.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return t||I(e,8,this.length),o.read(this,e,!1,52,8)},u.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||M(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i=0&&(i*=256);)this[t+o]=e/i&255;return t+n},u.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,255,0),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):N(this,e,t,!0),t+2},u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):N(this,e,t,!1),t+2},u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):R(this,e,t,!0),t+4},u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):R(this,e,t,!1),t+4},u.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+n},u.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=n-1,a=1,s=0;for(this[t+i]=255&e;--i>=0&&(a*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/a>>0)-s&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,127,-128),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):N(this,e,t,!0),t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):N(this,e,t,!1),t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):R(this,e,t,!0),t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):R(this,e,t,!1),t+4},u.prototype.writeFloatLE=function(e,t,n){return L(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return L(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return U(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return U(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else if(i<1e3||!u.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(i=t;i55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function z(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(q,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function V(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,n(36))},function(e,t,n){"use strict";e.exports={current:null}},function(e,t){e.exports=function(e){return null!=e&&"object"==typeof e}},function(e,t){var n,r,o=e.exports={};function i(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function s(e){if(n===setTimeout)return setTimeout(e,0);if((n===i||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:i}catch(e){n=i}try{r="function"==typeof clearTimeout?clearTimeout:a}catch(e){r=a}}();var u,c=[],l=!1,p=-1;function f(){l&&u&&(l=!1,u.length?c=u.concat(c):p=-1,c.length&&h())}function h(){if(!l){var e=s(f);l=!0;for(var t=c.length;t;){for(u=c,c=[];++p1)for(var n=1;n0&&"/"!==t[0]});function oe(e,t,n){return t=t||[],te.apply(void 0,[e].concat(u()(t))).get("parameters",Object(p.List)()).reduce(function(e,t){var r=n&&"body"===t.get("in")?t.get("value_xml"):t.get("value");return e.set(Object(l.B)(t,{allowHashes:!1}),r)},Object(p.fromJS)({}))}function ie(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(p.List.isList(e))return e.some(function(e){return p.Map.isMap(e)&&e.get("in")===t})}function ae(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(p.List.isList(e))return e.some(function(e){return p.Map.isMap(e)&&e.get("type")===t})}function se(e,t){t=t||[];var n=x(e).getIn(["paths"].concat(u()(t)),Object(p.fromJS)({})),r=e.getIn(["meta","paths"].concat(u()(t)),Object(p.fromJS)({})),o=ue(e,t),i=n.get("parameters")||new p.List,a=r.get("consumes_value")?r.get("consumes_value"):ae(i,"file")?"multipart/form-data":ae(i,"formData")?"application/x-www-form-urlencoded":void 0;return Object(p.fromJS)({requestContentType:a,responseContentType:o})}function ue(e,t){t=t||[];var n=x(e).getIn(["paths"].concat(u()(t)),null);if(null!==n){var r=e.getIn(["meta","paths"].concat(u()(t),["produces_value"]),null),o=n.getIn(["produces",0],null);return r||o||"application/json"}}function ce(e,t){t=t||[];var n=x(e),r=n.getIn(["paths"].concat(u()(t)),null);if(null!==r){var o=t,i=a()(o,1)[0],s=r.get("produces",null),c=n.getIn(["paths",i,"produces"],null),l=n.getIn(["produces"],null);return s||c||l}}function le(e,t){t=t||[];var n=x(e),r=n.getIn(["paths"].concat(u()(t)),null);if(null!==r){var o=t,i=a()(o,1)[0],s=r.get("consumes",null),c=n.getIn(["paths",i,"consumes"],null),l=n.getIn(["consumes"],null);return s||c||l}}var pe=function(e,t,n){var r=e.get("url").match(/^([a-z][a-z0-9+\-.]*):/),i=o()(r)?r[1]:null;return e.getIn(["scheme",t,n])||e.getIn(["scheme","_defaultScheme"])||i||""},fe=function(e,t,n){return["http","https"].indexOf(pe(e,t,n))>-1},he=function(e,t){t=t||[];var n=e.getIn(["meta","paths"].concat(u()(t),["parameters"]),Object(p.fromJS)([])),r=!0;return n.forEach(function(e){var t=e.get("errors");t&&t.count()&&(r=!1)}),r};function de(e){return p.Map.isMap(e)?e:new p.Map}},function(e,t,n){"use strict";n.r(t),n.d(t,"SHOW_AUTH_POPUP",function(){return d}),n.d(t,"AUTHORIZE",function(){return m}),n.d(t,"LOGOUT",function(){return v}),n.d(t,"PRE_AUTHORIZE_OAUTH2",function(){return g}),n.d(t,"AUTHORIZE_OAUTH2",function(){return y}),n.d(t,"VALIDATE",function(){return b}),n.d(t,"CONFIGURE_AUTH",function(){return _}),n.d(t,"showDefinitions",function(){return w}),n.d(t,"authorize",function(){return x}),n.d(t,"logout",function(){return E}),n.d(t,"preAuthorizeImplicit",function(){return S}),n.d(t,"authorizeOauth2",function(){return C}),n.d(t,"authorizePassword",function(){return k}),n.d(t,"authorizeApplication",function(){return O}),n.d(t,"authorizeAccessCodeWithFormParams",function(){return A}),n.d(t,"authorizeAccessCodeWithBasicAuthentication",function(){return T}),n.d(t,"authorizeRequest",function(){return j}),n.d(t,"configureAuth",function(){return P});var r=n(26),o=n.n(r),i=n(16),a=n.n(i),s=n(28),u=n.n(s),c=n(95),l=n.n(c),p=n(18),f=n.n(p),h=n(3),d="show_popup",m="authorize",v="logout",g="pre_authorize_oauth2",y="authorize_oauth2",b="validate",_="configure_auth";function w(e){return{type:d,payload:e}}function x(e){return{type:m,payload:e}}function E(e){return{type:v,payload:e}}var S=function(e){return function(t){var n=t.authActions,r=t.errActions,o=e.auth,i=e.token,a=e.isValid,s=o.schema,c=o.name,l=s.get("flow");delete f.a.swaggerUIRedirectOauth2,"accessCode"===l||a||r.newAuthErr({authId:c,source:"auth",level:"warning",message:"Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"}),i.error?r.newAuthErr({authId:c,source:"auth",level:"error",message:u()(i)}):n.authorizeOauth2({auth:o,token:i})}};function C(e){return{type:y,payload:e}}var k=function(e){return function(t){var n=t.authActions,r=e.schema,o=e.name,i=e.username,s=e.password,u=e.passwordType,c=e.clientId,l=e.clientSecret,p={grant_type:"password",scope:e.scopes.join(" "),username:i,password:s},f={};switch(u){case"request-body":!function(e,t,n){t&&a()(e,{client_id:t});n&&a()(e,{client_secret:n})}(p,c,l);break;case"basic":f.Authorization="Basic "+Object(h.a)(c+":"+l);break;default:console.warn("Warning: invalid passwordType ".concat(u," was passed, not including client id and secret"))}return n.authorizeRequest({body:Object(h.b)(p),url:r.get("tokenUrl"),name:o,headers:f,query:{},auth:e})}};var O=function(e){return function(t){var n=t.authActions,r=e.schema,o=e.scopes,i=e.name,a=e.clientId,s=e.clientSecret,u={Authorization:"Basic "+Object(h.a)(a+":"+s)},c={grant_type:"client_credentials",scope:o.join(" ")};return n.authorizeRequest({body:Object(h.b)(c),name:i,url:r.get("tokenUrl"),auth:e,headers:u})}},A=function(e){var t=e.auth,n=e.redirectUrl;return function(e){var r=e.authActions,o=t.schema,i=t.name,a=t.clientId,s=t.clientSecret,u=t.codeVerifier,c={grant_type:"authorization_code",code:t.code,client_id:a,client_secret:s,redirect_uri:n,code_verifier:u};return r.authorizeRequest({body:Object(h.b)(c),name:i,url:o.get("tokenUrl"),auth:t})}},T=function(e){var t=e.auth,n=e.redirectUrl;return function(e){var r=e.authActions,o=t.schema,i=t.name,a=t.clientId,s=t.clientSecret,u={Authorization:"Basic "+Object(h.a)(a+":"+s)},c={grant_type:"authorization_code",code:t.code,client_id:a,redirect_uri:n};return r.authorizeRequest({body:Object(h.b)(c),name:i,url:o.get("tokenUrl"),auth:t,headers:u})}},j=function(e){return function(t){var n,r=t.fn,i=t.getConfigs,s=t.authActions,c=t.errActions,p=t.oas3Selectors,f=t.specSelectors,h=t.authSelectors,d=e.body,m=e.query,v=void 0===m?{}:m,g=e.headers,y=void 0===g?{}:g,b=e.name,_=e.url,w=e.auth,x=(h.getConfigs()||{}).additionalQueryStringParams;n=f.isOAS3()?l()(_,p.selectedServer(),!0):l()(_,f.url(),!0),"object"===o()(x)&&(n.query=a()({},n.query,x));var E=n.toString(),S=a()({Accept:"application/json, text/plain, */*","Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest"},y);r.fetch({url:E,method:"post",headers:S,query:v,body:d,requestInterceptor:i().requestInterceptor,responseInterceptor:i().responseInterceptor}).then(function(e){var t=JSON.parse(e.data),n=t&&(t.error||""),r=t&&(t.parseError||"");e.ok?n||r?c.newAuthErr({authId:b,level:"error",source:"auth",message:u()(t)}):s.authorizeOauth2({auth:w,token:t}):c.newAuthErr({authId:b,level:"error",source:"auth",message:e.statusText})}).catch(function(e){var t=new Error(e).message;if(e.response&&e.response.data){var n=e.response.data;try{var r="string"==typeof n?JSON.parse(n):n;r.error&&(t+=", error: ".concat(r.error)),r.error_description&&(t+=", description: ".concat(r.error_description))}catch(e){}}c.newAuthErr({authId:b,level:"error",source:"auth",message:t})})}};function P(e){return{type:_,payload:e}}},function(e,t){var n=e.exports={version:"2.6.5"};"number"==typeof __e&&(__e=n)},function(e,t){e.exports=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,n){var r=n(127),o=Math.min;e.exports=function(e){return e>0?o(r(e),9007199254740991):0}},function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){var r=n(211),o=n(210);e.exports=function(e){return r(o(e))}},function(e,t,n){var r=n(49),o=n(133);e.exports=n(50)?function(e,t,n){return r.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){"use strict";e.exports=function(e){if("function"!=typeof e)throw new TypeError(e+" is not a function");return e}},function(e,t,n){"use strict";n.r(t),n.d(t,"UPDATE_LAYOUT",function(){return o}),n.d(t,"UPDATE_FILTER",function(){return i}),n.d(t,"UPDATE_MODE",function(){return a}),n.d(t,"SHOW",function(){return s}),n.d(t,"updateLayout",function(){return u}),n.d(t,"updateFilter",function(){return c}),n.d(t,"show",function(){return l}),n.d(t,"changeMode",function(){return p});var r=n(3),o="layout_update_layout",i="layout_update_filter",a="layout_update_mode",s="layout_show";function u(e){return{type:o,payload:e}}function c(e){return{type:i,payload:e}}function l(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return e=Object(r.w)(e),{type:s,payload:{thing:e,shown:t}}}function p(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return e=Object(r.w)(e),{type:a,payload:{thing:e,mode:t}}}},function(e,t,n){"use strict";(function(t){ +/*! + * @description Recursive object extending + * @author Viacheslav Lotsmanov + * @license MIT + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2018 Viacheslav Lotsmanov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +function n(e){return e instanceof t||e instanceof Date||e instanceof RegExp}function r(e){if(e instanceof t){var n=t.alloc?t.alloc(e.length):new t(e.length);return e.copy(n),n}if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return new RegExp(e);throw new Error("Unexpected situation")}function o(e){var t=[];return e.forEach(function(e,i){"object"==typeof e&&null!==e?Array.isArray(e)?t[i]=o(e):n(e)?t[i]=r(e):t[i]=a({},e):t[i]=e}),t}function i(e,t){return"__proto__"===t?void 0:e[t]}var a=e.exports=function(){if(arguments.length<1||"object"!=typeof arguments[0])return!1;if(arguments.length<2)return arguments[0];var e,t,s=arguments[0],u=Array.prototype.slice.call(arguments,1);return u.forEach(function(u){"object"!=typeof u||null===u||Array.isArray(u)||Object.keys(u).forEach(function(c){return t=i(s,c),(e=i(u,c))===s?void 0:"object"!=typeof e||null===e?void(s[c]=e):Array.isArray(e)?void(s[c]=o(e)):n(e)?void(s[c]=r(e)):"object"!=typeof t||null===t||Array.isArray(t)?void(s[c]=a({},e)):void(s[c]=a(t,e))})}),s}}).call(this,n(64).Buffer)},function(e,t,n){var r=n(151),o=n(336);e.exports=n(126)?function(e,t,n){return r.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t,n){var r=n(106),o=n(603),i=n(604),a="[object Null]",s="[object Undefined]",u=r?r.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?s:a:u&&u in Object(e)?o(e):i(e)}},function(e,t,n){var r=n(621),o=n(624);e.exports=function(e,t){var n=o(e,t);return r(n)?n:void 0}},function(e,t,n){var r=n(380),o=n(661),i=n(107);e.exports=function(e){return i(e)?r(e):o(e)}},function(e,t,n){"use strict";var r=n(178),o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=p;var i=n(137);i.inherits=n(47);var a=n(390),s=n(240);i.inherits(p,a);for(var u=o(s.prototype),c=0;c=t.length?{value:void 0,done:!0}:(e=r(t,n),this._i+=e.length,{value:e,done:!1})})},function(e,t){e.exports={}},function(e,t,n){n(561);for(var r=n(32),o=n(77),i=n(102),a=n(34)("toStringTag"),s="CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,TextTrackList,TouchList".split(","),u=0;u1){for(var d=Array(h),m=0;m1){for(var g=Array(v),y=0;y=this._finalSize&&(this._update(this._block),this._block.fill(0));var n=8*this._len;if(n<=4294967295)this._block.writeUInt32BE(n,this._blockSize-4);else{var r=(4294967295&n)>>>0,o=(n-r)/4294967296;this._block.writeUInt32BE(o,this._blockSize-8),this._block.writeUInt32BE(r,this._blockSize-4)}this._update(this._block);var i=this._hash();return e?i.toString(e):i},o.prototype._update=function(){throw new Error("_update must be implemented by subclass")},e.exports=o},function(e,t,n){var r=n(63),o=n(406),i=n(407),a=n(46),s=n(158),u=n(225),c={},l={};(t=e.exports=function(e,t,n,p,f){var h,d,m,v,g=f?function(){return e}:u(e),y=r(n,p,t?2:1),b=0;if("function"!=typeof g)throw TypeError(e+" is not iterable!");if(i(g)){for(h=s(e.length);h>b;b++)if((v=t?y(a(d=e[b])[0],d[1]):y(e[b]))===c||v===l)return v}else for(m=g.call(e);!(d=m.next()).done;)if((v=o(m,y,d.value,t))===c||v===l)return v}).BREAK=c,t.RETURN=l},function(e,t,n){"use strict";function r(e){return null==e}e.exports.isNothing=r,e.exports.isObject=function(e){return"object"==typeof e&&null!==e},e.exports.toArray=function(e){return Array.isArray(e)?e:r(e)?[]:[e]},e.exports.repeat=function(e,t){var n,r="";for(n=0;n1&&void 0!==arguments[1]?arguments[1]:{},r=Object(i.A)(t),a=r.type,s=r.example,u=r.properties,c=r.additionalProperties,l=r.items,p=n.includeReadOnly,f=n.includeWriteOnly;if(void 0!==s)return Object(i.e)(s,"$$ref",function(e){return"string"==typeof e&&e.indexOf("#")>-1});if(!a)if(u)a="object";else{if(!l)return;a="array"}if("object"===a){var d=Object(i.A)(u),m={};for(var v in d)d[v]&&d[v].deprecated||d[v]&&d[v].readOnly&&!p||d[v]&&d[v].writeOnly&&!f||(m[v]=e(d[v],n));if(!0===c)m.additionalProp1={};else if(c)for(var g=Object(i.A)(c),y=e(g,n),b=1;b<4;b++)m["additionalProp"+b]=y;return m}return"array"===a?o()(l.anyOf)?l.anyOf.map(function(t){return e(t,n)}):o()(l.oneOf)?l.oneOf.map(function(t){return e(t,n)}):[e(l,n)]:t.enum?t.default?t.default:Object(i.w)(t.enum)[0]:"file"!==a?h(t):void 0},m=function(e){return e.schema&&(e=e.schema),e.properties&&(e.type="object"),e},v=function e(t){var n,r,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s=p()({},Object(i.A)(t)),u=s.type,c=s.properties,l=s.additionalProperties,f=s.items,d=s.example,m=a.includeReadOnly,v=a.includeWriteOnly,g=s.default,y={},b={},_=t.xml,w=_.name,x=_.prefix,E=_.namespace,S=s.enum;if(!u)if(c||l)u="object";else{if(!f)return;u="array"}if(n=(x?x+":":"")+(w=w||"notagname"),E){var C=x?"xmlns:"+x:"xmlns";b[C]=E}if("array"===u&&f){if(f.xml=f.xml||_||{},f.xml.name=f.xml.name||_.name,_.wrapped)return y[n]=[],o()(d)?d.forEach(function(t){f.example=t,y[n].push(e(f,a))}):o()(g)?g.forEach(function(t){f.default=t,y[n].push(e(f,a))}):y[n]=[e(f,a)],b&&y[n].push({_attr:b}),y;var k=[];return o()(d)?(d.forEach(function(t){f.example=t,k.push(e(f,a))}),k):o()(g)?(g.forEach(function(t){f.default=t,k.push(e(f,a))}),k):e(f,a)}if("object"===u){var O=Object(i.A)(c);for(var A in y[n]=[],d=d||{},O)if(O.hasOwnProperty(A)&&(!O[A].readOnly||m)&&(!O[A].writeOnly||v))if(O[A].xml=O[A].xml||{},O[A].xml.attribute){var T=o()(O[A].enum)&&O[A].enum[0],j=O[A].example,P=O[A].default;b[O[A].xml.name||A]=void 0!==j&&j||void 0!==d[A]&&d[A]||void 0!==P&&P||T||h(O[A])}else{O[A].xml.name=O[A].xml.name||A,void 0===O[A].example&&void 0!==d[A]&&(O[A].example=d[A]);var I=e(O[A]);o()(I)?y[n]=y[n].concat(I):y[n].push(I)}return!0===l?y[n].push({additionalProp:"Anything can be here"}):l&&y[n].push({additionalProp:h(l)}),b&&y[n].push({_attr:b}),y}return r=void 0!==d?d:void 0!==g?g:o()(S)?S[0]:h(t),y[n]=b?[{_attr:b},r]:r,y};function g(e,t){var n=v(e,t);if(n)return s()(n,{declaration:!0,indent:"\t"})}var y=c()(g),b=c()(d)},function(e,t,n){"use strict";n.r(t),n.d(t,"UPDATE_CONFIGS",function(){return i}),n.d(t,"TOGGLE_CONFIGS",function(){return a}),n.d(t,"update",function(){return s}),n.d(t,"toggle",function(){return u}),n.d(t,"loaded",function(){return c});var r=n(2),o=n.n(r),i="configs_update",a="configs_toggle";function s(e,t){return{type:i,payload:o()({},e,t)}}function u(e){return{type:a,payload:e}}var c=function(){return function(){}}},function(e,t,n){"use strict";n.d(t,"a",function(){return a});var r=n(1),o=n.n(r),i=o.a.Set.of("type","format","items","default","maximum","exclusiveMaximum","minimum","exclusiveMinimum","maxLength","minLength","pattern","maxItems","minItems","uniqueItems","enum","multipleOf");function a(e){var t=(arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}).isOAS3;if(!o.a.Map.isMap(e))return{schema:o.a.Map(),parameterContentMediaType:null};if(!t)return"body"===e.get("in")?{schema:e.get("schema",o.a.Map()),parameterContentMediaType:null}:{schema:e.filter(function(e,t){return i.includes(t)}),parameterContentMediaType:null};if(e.get("content")){var n=e.get("content",o.a.Map({})).keySeq().first();return{schema:e.getIn(["content",n,"schema"],o.a.Map()),parameterContentMediaType:n}}return{schema:e.get("schema",o.a.Map()),parameterContentMediaType:null}}},function(e,t,n){e.exports=n(781)},function(e,t,n){"use strict";n.r(t);var r=n(469),o="object"==typeof self&&self&&self.Object===Object&&self,i=(r.a||o||Function("return this")()).Symbol,a=Object.prototype,s=a.hasOwnProperty,u=a.toString,c=i?i.toStringTag:void 0;var l=function(e){var t=s.call(e,c),n=e[c];try{e[c]=void 0;var r=!0}catch(e){}var o=u.call(e);return r&&(t?e[c]=n:delete e[c]),o},p=Object.prototype.toString;var f=function(e){return p.call(e)},h="[object Null]",d="[object Undefined]",m=i?i.toStringTag:void 0;var v=function(e){return null==e?void 0===e?d:h:m&&m in Object(e)?l(e):f(e)};var g=function(e,t){return function(n){return e(t(n))}}(Object.getPrototypeOf,Object);var y=function(e){return null!=e&&"object"==typeof e},b="[object Object]",_=Function.prototype,w=Object.prototype,x=_.toString,E=w.hasOwnProperty,S=x.call(Object);var C=function(e){if(!y(e)||v(e)!=b)return!1;var t=g(e);if(null===t)return!0;var n=E.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&x.call(n)==S},k=n(330),O={INIT:"@@redux/INIT"};function A(e,t,n){var r;if("function"==typeof t&&void 0===n&&(n=t,t=void 0),void 0!==n){if("function"!=typeof n)throw new Error("Expected the enhancer to be a function.");return n(A)(e,t)}if("function"!=typeof e)throw new Error("Expected the reducer to be a function.");var o=e,i=t,a=[],s=a,u=!1;function c(){s===a&&(s=a.slice())}function l(){return i}function p(e){if("function"!=typeof e)throw new Error("Expected listener to be a function.");var t=!0;return c(),s.push(e),function(){if(t){t=!1,c();var n=s.indexOf(e);s.splice(n,1)}}}function f(e){if(!C(e))throw new Error("Actions must be plain objects. Use custom middleware for async actions.");if(void 0===e.type)throw new Error('Actions may not have an undefined "type" property. Have you misspelled a constant?');if(u)throw new Error("Reducers may not dispatch actions.");try{u=!0,i=o(i,e)}finally{u=!1}for(var t=a=s,n=0;n0&&void 0!==arguments[0]?arguments[0]:{},t=arguments[1];if(a)throw a;for(var r=!1,o={},s=0;s0?r:n)(e)}},function(e,t){e.exports={}},function(e,t,n){var r=n(348),o=n(215);e.exports=Object.keys||function(e){return r(e,o)}},function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},function(e,t){e.exports=!0},function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){var r=n(49).f,o=n(75),i=n(34)("toStringTag");e.exports=function(e,t,n){e&&!o(e=n?e:e.prototype,i)&&r(e,i,{configurable:!0,value:t})}},function(e,t,n){var r=n(159)("meta"),o=n(43),i=n(75),a=n(49).f,s=0,u=Object.isExtensible||function(){return!0},c=!n(82)(function(){return u(Object.preventExtensions({}))}),l=function(e){a(e,r,{value:{i:"O"+ ++s,w:{}}})},p=e.exports={KEY:r,NEED:!1,fastKey:function(e,t){if(!o(e))return"symbol"==typeof e?e:("string"==typeof e?"S":"P")+e;if(!i(e,r)){if(!u(e))return"F";if(!t)return"E";l(e)}return e[r].i},getWeak:function(e,t){if(!i(e,r)){if(!u(e))return!0;if(!t)return!1;l(e)}return e[r].w},onFreeze:function(e){return c&&p.NEED&&u(e)&&!i(e,r)&&l(e),e}}},function(e,t,n){"use strict";e.exports=function(e){for(var t=arguments.length-1,n="Minified React error #"+e+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant="+e,r=0;r1&&void 0!==arguments[1]?arguments[1]:[],n={arrayBehaviour:(arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).arrayBehaviour||"replace"},r=t.map(function(e){return e||{}}),i=e||{},c=0;c1?t-1:0),r=1;r")}),p=function(){var e=/(?:)/,t=e.exec;e.exec=function(){return t.apply(this,arguments)};var n="ab".split(e);return 2===n.length&&"a"===n[0]&&"b"===n[1]}();e.exports=function(e,t,n){var f=s(e),h=!i(function(){var t={};return t[f]=function(){return 7},7!=""[e](t)}),d=h?!i(function(){var t=!1,n=/a/;return n.exec=function(){return t=!0,null},"split"===e&&(n.constructor={},n.constructor[c]=function(){return n}),n[f](""),!t}):void 0;if(!h||!d||"replace"===e&&!l||"split"===e&&!p){var m=/./[f],v=n(a,f,""[e],function(e,t,n,r,o){return t.exec===u?h&&!o?{done:!0,value:m.call(t,n,r)}:{done:!0,value:e.call(n,t,r)}:{done:!1}}),g=v[0],y=v[1];r(String.prototype,e,g),o(RegExp.prototype,f,2==t?function(e,t){return y.call(e,this,t)}:function(e){return y.call(e,this)})}}},function(e,t,n){var r=n(212),o=Math.min;e.exports=function(e){return e>0?o(r(e),9007199254740991):0}},function(e,t){var n=0,r=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++n+r).toString(36))}},function(e,t,n){var r=n(46),o=n(350),i=n(215),a=n(213)("IE_PROTO"),s=function(){},u=function(){var e,t=n(217)("iframe"),r=i.length;for(t.style.display="none",n(351).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write(" + + + + + + + +

+ + + +
+
+
+ +
+
+

Search Results

+ +
+
+ + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 00000000..937cd82c --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,104 @@ + + + + https://luet-lab.github.io/docs/docs/concepts/overview/build_packages/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/tutorials/hello_world/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/getting-started/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/concepts/overview/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/concepts/overview/repositories/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/concepts/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/concepts/packages/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/concepts/packages/specfile/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/concepts/overview/usage/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/tutorials/build_package/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/concepts/plugins-and-extensions/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/concepts/packages/templates/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/resources/arm/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/resources/building/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/concepts/packages/collections/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/concepts/overview/constraints/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/resources/faq/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/resources/scratch/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/tutorials/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/resources/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/blog/news/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/blog/releases/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/resources/references/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/docs/contribution-guidelines/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/blog/2019/12/23/0.3-release/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/blog/2019/12/23/website-is-up/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/index.json + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/about/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/blog/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/community/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/ + 2022-01-30T19:44:45+01:00 + + https://luet-lab.github.io/docs/search/ + 2022-01-30T19:44:45+01:00 + + diff --git a/tree.jpg b/tree.jpg new file mode 100644 index 00000000..c48d5273 Binary files /dev/null and b/tree.jpg differ diff --git a/webfonts/fa-brands-400.eot b/webfonts/fa-brands-400.eot new file mode 100644 index 00000000..2cca660d Binary files /dev/null and b/webfonts/fa-brands-400.eot differ diff --git a/webfonts/fa-brands-400.svg b/webfonts/fa-brands-400.svg new file mode 100644 index 00000000..d9939bc0 --- /dev/null +++ b/webfonts/fa-brands-400.svg @@ -0,0 +1,3451 @@ + + + + + +Created by FontForge 20190112 at Fri Aug 2 14:41:09 2019 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/webfonts/fa-brands-400.ttf b/webfonts/fa-brands-400.ttf new file mode 100644 index 00000000..2cb180bc Binary files /dev/null and b/webfonts/fa-brands-400.ttf differ diff --git a/webfonts/fa-brands-400.woff b/webfonts/fa-brands-400.woff new file mode 100644 index 00000000..e192c51c Binary files /dev/null and b/webfonts/fa-brands-400.woff differ diff --git a/webfonts/fa-brands-400.woff2 b/webfonts/fa-brands-400.woff2 new file mode 100644 index 00000000..e916d751 Binary files /dev/null and b/webfonts/fa-brands-400.woff2 differ diff --git a/webfonts/fa-regular-400.eot b/webfonts/fa-regular-400.eot new file mode 100644 index 00000000..54c89910 Binary files /dev/null and b/webfonts/fa-regular-400.eot differ diff --git a/webfonts/fa-regular-400.svg b/webfonts/fa-regular-400.svg new file mode 100644 index 00000000..e04c2e0e --- /dev/null +++ b/webfonts/fa-regular-400.svg @@ -0,0 +1,803 @@ + + + + + +Created by FontForge 20190112 at Fri Aug 2 14:41:09 2019 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/webfonts/fa-regular-400.ttf b/webfonts/fa-regular-400.ttf new file mode 100644 index 00000000..ef43cfd3 Binary files /dev/null and b/webfonts/fa-regular-400.ttf differ diff --git a/webfonts/fa-regular-400.woff b/webfonts/fa-regular-400.woff new file mode 100644 index 00000000..13f01914 Binary files /dev/null and b/webfonts/fa-regular-400.woff differ diff --git a/webfonts/fa-regular-400.woff2 b/webfonts/fa-regular-400.woff2 new file mode 100644 index 00000000..004b29b6 Binary files /dev/null and b/webfonts/fa-regular-400.woff2 differ diff --git a/webfonts/fa-solid-900.eot b/webfonts/fa-solid-900.eot new file mode 100644 index 00000000..8f113689 Binary files /dev/null and b/webfonts/fa-solid-900.eot differ diff --git a/webfonts/fa-solid-900.svg b/webfonts/fa-solid-900.svg new file mode 100644 index 00000000..b80d4772 --- /dev/null +++ b/webfonts/fa-solid-900.svg @@ -0,0 +1,4649 @@ + + + + + +Created by FontForge 20190112 at Fri Aug 2 14:41:09 2019 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/webfonts/fa-solid-900.ttf b/webfonts/fa-solid-900.ttf new file mode 100644 index 00000000..5a6d7476 Binary files /dev/null and b/webfonts/fa-solid-900.ttf differ diff --git a/webfonts/fa-solid-900.woff b/webfonts/fa-solid-900.woff new file mode 100644 index 00000000..d92df456 Binary files /dev/null and b/webfonts/fa-solid-900.woff differ diff --git a/webfonts/fa-solid-900.woff2 b/webfonts/fa-solid-900.woff2 new file mode 100644 index 00000000..df7e7042 Binary files /dev/null and b/webfonts/fa-solid-900.woff2 differ