diff --git a/pr-preview/pr-59/_/css/site.css b/pr-preview/pr-59/_/css/site.css new file mode 100644 index 0000000..c39da22 --- /dev/null +++ b/pr-preview/pr-59/_/css/site.css @@ -0,0 +1,2608 @@ +@font-face { + font-family: Roboto; + font-style: normal; + font-weight: 400; + src: url(../font/roboto-latin-400-normal.woff2) format("woff2"), url(../font/roboto-latin-400-normal.woff) format("woff"); + unicode-range: U+00??, U+0131, U+0152-0153, U+02bb-02bc, U+02c6, U+02da, U+02dc, U+2000-206f, U+2074, U+20ac, U+2122, U+2191, U+2193, U+2212, U+2215, U+feff, U+fffd +} + +@font-face { + font-family: Roboto; + font-style: italic; + font-weight: 400; + src: url(../font/roboto-latin-400-italic.woff2) format("woff2"), url(../font/roboto-latin-400-italic.woff) format("woff"); + unicode-range: U+00??, U+0131, U+0152-0153, U+02bb-02bc, U+02c6, U+02da, U+02dc, U+2000-206f, U+2074, U+20ac, U+2122, U+2191, U+2193, U+2212, U+2215, U+feff, U+fffd +} + +@font-face { + font-family: Roboto; + font-style: normal; + font-weight: 500; + src: url(../font/roboto-latin-500-normal.woff2) format("woff2"), url(../font/roboto-latin-500-normal.woff) format("woff"); + unicode-range: U+00??, U+0131, U+0152-0153, U+02bb-02bc, U+02c6, U+02da, U+02dc, U+2000-206f, U+2074, U+20ac, U+2122, U+2191, U+2193, U+2212, U+2215, U+feff, U+fffd +} + +@font-face { + font-family: Roboto; + font-style: italic; + font-weight: 500; + src: url(../font/roboto-latin-500-italic.woff2) format("woff2"), url(../font/roboto-latin-500-italic.woff) format("woff"); + unicode-range: U+00??, U+0131, U+0152-0153, U+02bb-02bc, U+02c6, U+02da, U+02dc, U+2000-206f, U+2074, U+20ac, U+2122, U+2191, U+2193, U+2212, U+2215, U+feff, U+fffd +} + +@font-face { + font-family: Roboto Mono; + font-style: normal; + font-weight: 400; + src: url(../font/roboto-mono-latin-400-normal.woff2) format("woff2"), url(../font/roboto-mono-latin-400-normal.woff) format("woff"); + unicode-range: U+00??, U+0131, U+0152-0153, U+02bb-02bc, U+02c6, U+02da, U+02dc, U+2000-206f, U+2074, U+20ac, U+2122, U+2191, U+2193, U+2212, U+2215, U+feff, U+fffd +} + +@font-face { + font-family: Roboto Mono; + font-style: normal; + font-weight: 500; + src: url(../font/roboto-mono-latin-500-normal.woff2) format("woff2"), url(../font/roboto-mono-latin-500-normal.woff) format("woff"); + unicode-range: U+00??, U+0131, U+0152-0153, U+02bb-02bc, U+02c6, U+02da, U+02dc, U+2000-206f, U+2074, U+20ac, U+2122, U+2191, U+2193, U+2212, U+2215, U+feff, U+fffd +} + +*, +::after, +::before { + -webkit-box-sizing: inherit; + box-sizing: inherit +} + +html { + -webkit-box-sizing: border-box; + box-sizing: border-box; + font-size: 1.0625em; + height: 100%; + scroll-behavior: smooth +} + +@media screen and (min-width:1024px) { + html { + font-size: 1.125em + } +} + +body { + background: #fff; + color: #222; + font-family: Roboto, sans-serif; + line-height: 1.15; + margin: 0; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + word-wrap: anywhere +} + +a { + text-decoration: none +} + +a:hover { + text-decoration: underline +} + +a:active { + background-color: none +} + +code, +kbd, +pre { + font-family: Roboto Mono, monospace +} + +b, +dt, +strong, +th { + font-weight: 500 +} + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline +} + +sub { + bottom: -.25em +} + +sup { + top: -.5em +} + +em em { + font-style: normal +} + +strong strong { + font-weight: 400 +} + +button { + cursor: pointer; + font-family: inherit; + font-size: 1em; + line-height: 1.15; + margin: 0 +} + +button::-moz-focus-inner { + border: none; + padding: 0 +} + +summary { + cursor: pointer; + -webkit-tap-highlight-color: transparent; + outline: none +} + +table { + border-collapse: collapse; + word-wrap: normal +} + +object[type="image/svg+xml"]:not([width]) { + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content +} + +::-webkit-input-placeholder { + opacity: .5 +} + +::-moz-placeholder { + opacity: .5 +} + +:-ms-input-placeholder { + opacity: .5 +} + +::-ms-input-placeholder { + opacity: .5 +} + +::placeholder { + opacity: .5 +} + +@media (pointer:fine) { + @supports (scrollbar-width:thin) { + html { + scrollbar-color: #c1c1c1 #fafafa + } + + body * { + scrollbar-width: thin; + scrollbar-color: #c1c1c1 transparent + } + } + + html::-webkit-scrollbar { + background-color: #fafafa; + height: 12px; + width: 12px + } + + body ::-webkit-scrollbar { + height: 6px; + width: 6px + } + + ::-webkit-scrollbar-thumb { + background-clip: padding-box; + background-color: #c1c1c1; + border: 3px solid transparent; + border-radius: 12px + } + + body ::-webkit-scrollbar-thumb { + border-width: 1.75px; + border-radius: 6px + } + + ::-webkit-scrollbar-thumb:hover { + background-color: #9c9c9c + } +} + +@media screen and (min-width:1024px) { + .body { + display: -webkit-box; + display: -ms-flexbox; + display: flex + } +} + +.nav-container { + position: fixed; + top: 3.5rem; + left: 0; + width: 100%; + font-size: .94444rem; + z-index: 1; + visibility: hidden +} + +@media screen and (min-width:769px) { + .nav-container { + width: 15rem + } +} + +@media screen and (min-width:1024px) { + .nav-container { + font-size: .86111rem; + -webkit-box-flex: 0; + -ms-flex: none; + flex: none; + position: static; + top: 0; + visibility: visible + } +} + +.nav-container.is-active { + visibility: visible +} + +.nav { + background: #fafafa; + position: relative; + top: 2.5rem; + height: calc(100vh - 6rem) +} + +@media screen and (min-width:769px) { + .nav { + -webkit-box-shadow: .5px 0 3px #c1c1c1; + box-shadow: .5px 0 3px #c1c1c1 + } +} + +@media screen and (min-width:1024px) { + .nav { + top: 3.5rem; + -webkit-box-shadow: none; + box-shadow: none; + position: sticky; + height: calc(100vh - 3.5rem) + } +} + +.nav a { + color: inherit +} + +.nav .panels { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + height: inherit +} + +html.is-clipped--nav { + overflow-y: hidden +} + +.nav-panel-menu { + overflow-y: scroll; + -ms-scroll-chaining: none; + overscroll-behavior: none; + height: calc(100% - 2.5rem) +} + +.nav-panel-menu:not(.is-active) .nav-menu { + opacity: .75 +} + +.nav-panel-menu:not(.is-active)::after { + content: ""; + background: rgba(0, 0, 0, .5); + display: block; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0 +} + +.nav-menu { + min-height: 100%; + padding: .5rem .75rem; + line-height: 1.35; + position: relative +} + +.nav-menu h3.title { + color: #424242; + font-size: inherit; + font-weight: 500; + margin: 0; + padding: .25em 0 .125em +} + +.nav-list { + list-style: none; + margin: 0 0 0 .75rem; + padding: 0 +} + +.nav-menu>.nav-list+.nav-list { + margin-top: .5rem +} + +.nav-item { + margin-top: .5em +} + +.nav-item-toggle~.nav-list { + padding-bottom: .125rem +} + +.nav-item[data-depth="0"]>.nav-list:first-child { + display: block; + margin: 0 +} + +.nav-item:not(.is-active)>.nav-list { + display: none +} + +.nav-item-toggle { + background: transparent url(../img/caret.svg) no-repeat 50%/50%; + border: none; + outline: none; + line-height: inherit; + padding: 0; + position: absolute; + height: 1.35em; + width: 1.35em; + margin-top: -.05em; + margin-left: -1.35em +} + +.nav-item.is-active>.nav-item-toggle { + -webkit-transform: rotate(90deg); + transform: rotate(90deg) +} + +.is-current-page>.nav-link, +.is-current-page>.nav-text { + font-weight: 500 +} + +.nav-panel-explore { + background: #fafafa; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0 +} + +.nav-panel-explore:not(:first-child) { + top: auto; + max-height: calc(50% + 2.5rem) +} + +.nav-panel-explore .context { + font-size: .83333rem; + -ms-flex-negative: 0; + flex-shrink: 0; + color: #5d5d5d; + -webkit-box-shadow: 0 -1px 0 #e1e1e1; + box-shadow: 0 -1px 0 #e1e1e1; + padding: 0 .5rem; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + line-height: 1; + height: 2.5rem +} + +.nav-panel-explore:not(:first-child) .context { + cursor: pointer +} + +.nav-panel-explore .context .version { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: inherit; + -ms-flex-align: inherit; + align-items: inherit +} + +.nav-panel-explore .context .version::after { + content: ""; + background: url(../img/chevron.svg) no-repeat 100%/auto 100%; + width: 1.25em; + height: .75em +} + +.nav-panel-explore .components { + line-height: 1.6; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + -webkit-box-shadow: inset 0 1px 5px #e1e1e1; + box-shadow: inset 0 1px 5px #e1e1e1; + background: #f0f0f0; + padding: .5rem .75rem 0; + margin: 0; + overflow-y: scroll; + -ms-scroll-chaining: none; + overscroll-behavior: none; + max-height: 100%; + display: block +} + +.nav-panel-explore:not(.is-active) .components { + display: none +} + +.nav-panel-explore .component { + display: block +} + +.nav-panel-explore .component+.component { + margin-top: .5rem +} + +.nav-panel-explore .component:last-child { + margin-bottom: .75rem +} + +.nav-panel-explore .component .title { + font-weight: 500 +} + +.nav-panel-explore .versions { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding-left: 0; + margin-top: -.25rem; + line-height: 1; + list-style: none +} + +.nav-panel-explore .component .version { + margin: .375rem .375rem 0 0 +} + +.nav-panel-explore .component .version a { + border: 1px solid #c1c1c1; + border-radius: .25rem; + opacity: .75; + white-space: nowrap; + padding: .125em .25em; + display: inherit +} + +.nav-panel-explore .component .is-current a { + border-color: currentColor; + opacity: .9; + font-weight: 500 +} + +@media screen and (max-width:1023.5px) { + aside.toc.sidebar { + display: none + } + + main>.content { + overflow-x: auto + } +} + +@media screen and (min-width:1024px) { + main { + -webkit-box-flex: 1; + -ms-flex: auto; + flex: auto; + min-width: 0 + } + + main>.content { + display: -webkit-box; + display: -ms-flexbox; + display: flex + } + + aside.toc.embedded { + display: none + } + + aside.toc.sidebar { + -webkit-box-flex: 0; + -ms-flex: 0 0 9rem; + flex: 0 0 9rem; + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1 + } +} + +@media screen and (min-width:1216px) { + aside.toc.sidebar { + -ms-flex-preferred-size: 12rem; + flex-basis: 12rem + } +} + +.toolbar { + color: #5d5d5d; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + background-color: #fafafa; + -webkit-box-shadow: 0 1px 0 #e1e1e1; + box-shadow: 0 1px 0 #e1e1e1; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + font-size: .83333rem; + height: 2.5rem; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + position: sticky; + top: 3.5rem; + z-index: 2 +} + +.toolbar a { + color: inherit +} + +.nav-toggle { + background: url(../img/menu.svg) no-repeat 50% 47.5%; + background-size: 49%; + border: none; + outline: none; + line-height: inherit; + padding: 0; + height: 2.5rem; + width: 2.5rem; + margin-right: -.25rem +} + +@media screen and (min-width:1024px) { + .nav-toggle { + display: none + } +} + +.nav-toggle.is-active { + background-image: url(../img/back.svg); + background-size: 41.5% +} + +.home-link { + display: block; + background: url(../img/home-o.svg) no-repeat 50%; + height: 1.25rem; + width: 1.25rem; + margin: .625rem +} + +.home-link.is-current, +.home-link:hover { + background-image: url(../img/home.svg) +} + +.edit-this-page { + display: none; + padding-right: .5rem +} + +@media screen and (min-width:1024px) { + .edit-this-page { + display: block + } +} + +.toolbar .edit-this-page a { + color: #8e8e8e +} + +.breadcrumbs { + display: none; + -webkit-box-flex: 1; + -ms-flex: 1 1; + flex: 1 1; + padding: 0 .5rem 0 .75rem; + line-height: 1.35 +} + +@media screen and (min-width:1024px) { + .breadcrumbs { + display: block + } +} + +a+.breadcrumbs { + padding-left: .05rem +} + +.breadcrumbs ul { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin: 0; + padding: 0; + list-style: none +} + +.breadcrumbs li { + display: inline; + margin: 0 +} + +.breadcrumbs li::after { + content: "/"; + padding: 0 .5rem +} + +.breadcrumbs li:last-of-type::after { + content: none +} + +.page-versions { + margin: 0 .2rem 0 auto; + position: relative; + line-height: 1 +} + +@media screen and (min-width:1024px) { + .page-versions { + margin-right: .7rem + } +} + +.page-versions .version-menu-toggle { + color: inherit; + background: url(../img/chevron.svg) no-repeat; + background-position: right .5rem top 50%; + background-size: auto .75em; + border: none; + outline: none; + line-height: inherit; + padding: .5rem 1.5rem .5rem .5rem; + position: relative; + z-index: 3 +} + +.page-versions .version-menu { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + min-width: 100%; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-align: end; + -ms-flex-align: end; + align-items: flex-end; + background: -webkit-gradient(linear, left top, left bottom, from(#f0f0f0), to(#f0f0f0)) no-repeat; + background: linear-gradient(180deg, #f0f0f0 0, #f0f0f0) no-repeat; + padding: 1.375rem 1.5rem .5rem .5rem; + position: absolute; + top: 0; + right: 0; + white-space: nowrap +} + +.page-versions:not(.is-active) .version-menu { + display: none +} + +.page-versions .version { + display: block; + padding-top: .5rem +} + +.page-versions .version.is-current { + display: none +} + +.page-versions .version.is-missing { + color: #8e8e8e; + font-style: italic; + text-decoration: none +} + +.toc-menu { + color: #5d5d5d +} + +.toc.sidebar .toc-menu { + margin-right: .75rem; + position: sticky; + top: 6rem +} + +.toc .toc-menu h3 { + color: #333; + font-size: .88889rem; + font-weight: 500; + line-height: 1.3; + margin: 0 -.5px; + padding-bottom: .25rem +} + +.toc.sidebar .toc-menu h3 { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + height: 2.5rem; + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end +} + +.toc .toc-menu ul { + font-size: .83333rem; + line-height: 1.2; + list-style: none; + margin: 0; + padding: 0 +} + +.toc.sidebar .toc-menu ul { + max-height: calc(100vh - 8.5rem); + overflow-y: auto; + -ms-scroll-chaining: none; + overscroll-behavior: none +} + +@supports (scrollbar-width:none) { + .toc.sidebar .toc-menu ul { + scrollbar-width: none + } +} + +.toc .toc-menu ul::-webkit-scrollbar { + width: 0; + height: 0 +} + +@media screen and (min-width:1024px) { + .toc .toc-menu h3 { + font-size: .83333rem + } + + .toc .toc-menu ul { + font-size: .75rem + } +} + +.toc .toc-menu li { + margin: 0 +} + +.toc .toc-menu li[data-level="2"] a { + padding-left: 1.25rem +} + +.toc .toc-menu li[data-level="3"] a { + padding-left: 2rem +} + +.toc .toc-menu a { + color: inherit; + border-left: 2px solid #e1e1e1; + display: inline-block; + padding: .25rem 0 .25rem .5rem; + text-decoration: none +} + +.sidebar.toc .toc-menu a { + display: block; + outline: none +} + +.toc .toc-menu a:hover { + color: #1565c0 +} + +.toc .toc-menu a.is-active { + border-left-color: #1565c0; + color: #333 +} + +.sidebar.toc .toc-menu a:focus { + background: #fafafa +} + +.toc .toc-menu .is-hidden-toc { + display: none !important +} + +.doc { + color: #333; + font-size: inherit; + -webkit-hyphens: auto; + -ms-hyphens: auto; + hyphens: auto; + line-height: 1.6; + margin: 0 auto; + max-width: 40rem; + padding: 0 1rem 4rem +} + +@media screen and (min-width:1024px) { + .doc { + -webkit-box-flex: 1; + -ms-flex: auto; + flex: auto; + font-size: .94444rem; + margin: 0 2rem; + max-width: 46rem; + min-width: 0 + } +} + +.doc h1, +.doc h2, +.doc h3, +.doc h4, +.doc h5, +.doc h6 { + color: #191919; + font-weight: 400; + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + line-height: 1.3; + margin: 1rem 0 0 +} + +.doc>h1.page:first-child { + font-size: 2rem; + margin: 1.5rem 0 +} + +@media screen and (min-width:769px) { + .doc>h1.page:first-child { + margin-top: 2.5rem + } +} + +.doc>h1.page:first-child+aside.toc.embedded { + margin-top: -.5rem +} + +.doc>h2#name+.sectionbody { + margin-top: 1rem +} + +#preamble+.sect1, +.doc .sect1+.sect1 { + margin-top: 2rem +} + +.doc h1.sect0 { + background: #f0f0f0; + font-size: 1.8em; + margin: 1.5rem -1rem 0; + padding: .5rem 1rem +} + +.doc h2:not(.discrete) { + border-bottom: 1px solid #e1e1e1; + margin-left: -1rem; + margin-right: -1rem; + padding: .4rem 1rem .1rem +} + +.doc h3:not(.discrete), +.doc h4:not(.discrete) { + font-weight: 500 +} + +.doc h1 .anchor, +.doc h2 .anchor, +.doc h3 .anchor, +.doc h4 .anchor, +.doc h5 .anchor, +.doc h6 .anchor { + position: absolute; + text-decoration: none; + width: 1.75ex; + margin-left: -1.5ex; + visibility: hidden; + font-size: .8em; + font-weight: 400; + padding-top: .05em +} + +.doc h1 .anchor::before, +.doc h2 .anchor::before, +.doc h3 .anchor::before, +.doc h4 .anchor::before, +.doc h5 .anchor::before, +.doc h6 .anchor::before { + content: "\00a7" +} + +.doc h1:hover .anchor, +.doc h2:hover .anchor, +.doc h3:hover .anchor, +.doc h4:hover .anchor, +.doc h5:hover .anchor, +.doc h6:hover .anchor { + visibility: visible +} + +.doc dl, +.doc p { + margin: 0 +} + +.doc a { + color: #1565c0 +} + +.doc a:hover { + color: #104d92 +} + +.doc a.bare { + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none +} + +.doc a.unresolved { + color: #d32f2f +} + +.doc i.fa { + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + font-style: normal +} + +.doc .colist>table code, +.doc p code, +.doc thead code { + color: #222; + background: #fafafa; + border-radius: .25em; + font-size: .95em; + padding: .125em .25em +} + +.doc code, +.doc pre { + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none +} + +.doc pre { + font-size: .88889rem; + line-height: 1.5; + margin: 0 +} + +.doc blockquote { + margin: 0 +} + +.doc .paragraph.lead>p { + font-size: 1rem +} + +.doc .right { + float: right +} + +.doc .left { + float: left +} + +.doc .float-gap.right { + margin: 0 1rem 1rem 0 +} + +.doc .float-gap.left { + margin: 0 0 1rem 1rem +} + +.doc .float-group::after { + content: ""; + display: table; + clear: both +} + +.doc .stretch { + width: 100% +} + +.doc .underline { + text-decoration: underline +} + +.doc .line-through { + text-decoration: line-through +} + +.doc .dlist, +.doc .exampleblock, +.doc .hdlist, +.doc .imageblock, +.doc .listingblock, +.doc .literalblock, +.doc .olist, +.doc .paragraph, +.doc .partintro, +.doc .quoteblock, +.doc .sidebarblock, +.doc .tabs, +.doc .ulist, +.doc .verseblock, +.doc .videoblock, +.doc details, +.doc hr { + margin: 1rem 0 0 +} + +.doc table.tableblock { + font-size: .83333rem +} + +.doc .tablecontainer, +.doc .tablecontainer+*, +.doc :not(.tablecontainer)>table.tableblock, +.doc :not(.tablecontainer)>table.tableblock+* { + margin-top: 1.5rem +} + +.doc p.tableblock+p.tableblock { + margin-top: .5rem +} + +.doc td.tableblock>.content>:first-child { + margin-top: 0 +} + +.doc table.tableblock td, +.doc table.tableblock th { + padding: .5rem +} + +.doc table.tableblock, +.doc table.tableblock>*>tr>* { + border: 0 solid #e1e1e1 +} + +.doc table.grid-all>*>tr>* { + border-width: 1px +} + +.doc table.grid-cols>*>tr>* { + border-width: 0 1px +} + +.doc table.grid-rows>*>tr>* { + border-width: 1px 0 +} + +.doc table.grid-all>thead th, +.doc table.grid-rows>thead th { + border-bottom-width: 2.5px +} + +.doc table.frame-all { + border-width: 1px +} + +.doc table.frame-ends { + border-width: 1px 0 +} + +.doc table.frame-sides { + border-width: 0 1px +} + +.doc table.frame-none>colgroup+*>:first-child>*, +.doc table.frame-sides>colgroup+*>:first-child>* { + border-top-width: 0 +} + +.doc table.frame-sides>:last-child>:last-child>* { + border-bottom-width: 0 +} + +.doc table.frame-ends>*>tr>:first-child, +.doc table.frame-none>*>tr>:first-child { + border-left-width: 0 +} + +.doc table.frame-ends>*>tr>:last-child, +.doc table.frame-none>*>tr>:last-child { + border-right-width: 0 +} + +.doc table.stripes-all>tbody>tr, +.doc table.stripes-even>tbody>tr:nth-of-type(2n), +.doc table.stripes-hover>tbody>tr:hover, +.doc table.stripes-odd>tbody>tr:nth-of-type(odd) { + background: #fafafa +} + +.doc table.tableblock>tfoot { + background: -webkit-gradient(linear, left top, left bottom, from(#f0f0f0), to(#fff)); + background: linear-gradient(180deg, #f0f0f0 0, #fff) +} + +.doc .halign-left { + text-align: left +} + +.doc .halign-right { + text-align: right +} + +.doc .halign-center { + text-align: center +} + +.doc .valign-top { + vertical-align: top +} + +.doc .valign-bottom { + vertical-align: bottom +} + +.doc .valign-middle { + vertical-align: middle +} + +.doc .admonitionblock { + margin: 1.4rem 0 0 +} + +.doc .admonitionblock p, +.doc .admonitionblock td.content { + font-size: .88889rem +} + +.doc .admonitionblock td.content>.title+*, +.doc .admonitionblock td.content>:not(.title):first-child { + margin-top: 0 +} + +.doc .admonitionblock pre { + font-size: .83333rem +} + +.doc .admonitionblock>table { + table-layout: fixed; + position: relative; + width: 100% +} + +.doc .admonitionblock td.content { + padding: 1rem 1rem .75rem; + background: #fafafa; + width: 100%; + word-wrap: anywhere +} + +.doc .admonitionblock .icon { + position: absolute; + top: 0; + left: 0; + font-size: .83333rem; + padding: 0 .5rem; + height: 1.25rem; + line-height: 1; + font-weight: 500; + text-transform: uppercase; + border-radius: .45rem; + -webkit-transform: translate(-.5rem, -50%); + transform: translate(-.5rem, -50%) +} + +.doc .admonitionblock.caution .icon { + background-color: #a0439c; + color: #fff +} + +.doc .admonitionblock.important .icon { + background-color: #d32f2f; + color: #fff +} + +.doc .admonitionblock.note .icon { + background-color: #217ee7; + color: #fff +} + +.doc .admonitionblock.tip .icon { + background-color: #41af46; + color: #fff +} + +.doc .admonitionblock.warning .icon { + background-color: #e18114; + color: #fff +} + +.doc .admonitionblock .icon i { + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + height: 100% +} + +.doc .admonitionblock .icon i::after { + content: attr(title) +} + +.doc .imageblock, +.doc .videoblock { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center +} + +.doc .imageblock.text-left, +.doc .videoblock.text-left { + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start +} + +.doc .imageblock.text-right, +.doc .videoblock.text-right { + -webkit-box-align: end; + -ms-flex-align: end; + align-items: flex-end +} + +.doc .image>img, +.doc .image>object, +.doc .image>svg, +.doc .imageblock img, +.doc .imageblock object, +.doc .imageblock svg { + display: inline-block; + height: auto; + max-width: 100%; + vertical-align: middle +} + +.doc .image:not(.left):not(.right)>img { + margin-top: -.2em +} + +.doc .videoblock iframe { + max-width: 100%; + vertical-align: middle +} + +#preamble .abstract blockquote { + background: #f0f0f0; + border-left: 5px solid #e1e1e1; + color: #4a4a4a; + font-size: .88889rem; + padding: .75em 1em +} + +.doc .quoteblock, +.doc .verseblock { + background: #fafafa; + border-left: 5px solid #5d5d5d; + color: #5d5d5d +} + +.doc .quoteblock { + padding: .25rem 2rem 1.25rem +} + +.doc .quoteblock .attribution { + color: #8e8e8e; + font-size: .83333rem; + margin-top: .75rem +} + +.doc .quoteblock blockquote { + margin-top: 1rem +} + +.doc .quoteblock .paragraph { + font-style: italic +} + +.doc .quoteblock cite { + padding-left: 1em +} + +.doc .verseblock { + font-size: 1.15em; + padding: 1rem 2rem +} + +.doc .verseblock pre { + font-family: inherit; + font-size: inherit +} + +.doc ol, +.doc ul { + margin: 0; + padding: 0 0 0 2rem +} + +.doc ol.none, +.doc ol.unnumbered, +.doc ol.unstyled, +.doc ul.checklist, +.doc ul.no-bullet, +.doc ul.none, +.doc ul.unstyled { + list-style-type: none +} + +.doc ol.unnumbered, +.doc ul.no-bullet { + padding-left: 1.25rem +} + +.doc ol.unstyled, +.doc ul.unstyled { + padding-left: 0 +} + +.doc ul.circle { + list-style-type: circle +} + +.doc ul.disc { + list-style-type: disc +} + +.doc ul.square { + list-style-type: square +} + +.doc ul.circle ul:not([class]), +.doc ul.disc ul:not([class]), +.doc ul.square ul:not([class]) { + list-style: inherit +} + +.doc ol.arabic { + list-style-type: decimal +} + +.doc ol.decimal { + list-style-type: decimal-leading-zero +} + +.doc ol.loweralpha { + list-style-type: lower-alpha +} + +.doc ol.upperalpha { + list-style-type: upper-alpha +} + +.doc ol.lowerroman { + list-style-type: lower-roman +} + +.doc ol.upperroman { + list-style-type: upper-roman +} + +.doc ol.lowergreek { + list-style-type: lower-greek +} + +.doc ul.checklist { + padding-left: 1.75rem +} + +.doc ul.checklist p>i.fa-check-square-o:first-child, +.doc ul.checklist p>i.fa-square-o:first-child { + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + width: 1.25rem; + margin-left: -1.25rem +} + +.doc ul.checklist i.fa-check-square-o::before { + content: "\2713" +} + +.doc ul.checklist i.fa-square-o::before { + content: "\274f" +} + +.doc .dlist .dlist, +.doc .dlist .olist, +.doc .dlist .ulist, +.doc .olist .dlist, +.doc .olist .olist, +.doc .olist .ulist, +.doc .olist li+li, +.doc .ulist .dlist, +.doc .ulist .olist, +.doc .ulist .ulist, +.doc .ulist li+li { + margin-top: .5rem +} + +.doc .admonitionblock .listingblock, +.doc .olist .listingblock, +.doc .ulist .listingblock { + padding: 0 +} + +.doc .admonitionblock .title, +.doc .exampleblock .title, +.doc .imageblock .title, +.doc .listingblock .title, +.doc .literalblock .title, +.doc .openblock .title, +.doc .tableblock caption, +.doc .videoblock .title { + color: #5d5d5d; + font-size: .88889rem; + font-style: italic; + font-weight: 500; + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + letter-spacing: .01em; + padding-bottom: .075rem +} + +.doc .tableblock caption { + text-align: left +} + +.doc .olist .title, +.doc .ulist .title { + font-style: italic; + font-weight: 500; + margin-bottom: .25rem +} + +.doc .imageblock .title { + margin-top: .5rem; + padding-bottom: 0 +} + +.doc details { + margin-left: 1rem +} + +.doc details>summary { + display: block; + position: relative; + line-height: 1.6; + margin-bottom: .5rem +} + +.doc details>summary::-webkit-details-marker { + display: none +} + +.doc details>summary::before { + content: ""; + border: solid transparent; + border-left: solid; + border-width: .3em 0 .3em .5em; + position: absolute; + top: .5em; + left: -1rem; + -webkit-transform: translateX(15%); + transform: translateX(15%) +} + +.doc details[open]>summary::before { + border-color: currentColor transparent transparent; + border-width: .5rem .3rem 0; + -webkit-transform: translateY(15%); + transform: translateY(15%) +} + +.doc details>summary::after { + content: ""; + width: 1rem; + height: 1em; + position: absolute; + top: .3em; + left: -1rem +} + +.doc details.result { + margin-top: .25rem +} + +.doc details.result>summary { + color: #5d5d5d; + font-style: italic; + margin-bottom: 0 +} + +.doc details.result>.content { + margin-left: -1rem +} + +.doc .exampleblock>.content, +.doc details.result>.content { + background: #fff; + border: .25rem solid #5d5d5d; + border-radius: .5rem; + padding: .75rem +} + +.doc .exampleblock>.content::after, +.doc details.result>.content::after { + content: ""; + display: table; + clear: both +} + +.doc .exampleblock>.content>:first-child, +.doc details>.content>:first-child { + margin-top: 0 +} + +.doc .sidebarblock { + background: #e1e1e1; + border-radius: .75rem; + padding: .75rem 1.5rem +} + +.doc .sidebarblock>.content>.title { + font-size: 1.25rem; + font-weight: 500; + line-height: 1.3; + margin-bottom: -.3em; + text-align: center +} + +.doc .sidebarblock>.content>:not(.title):first-child { + margin-top: 0 +} + +.doc .listingblock.wrap pre, +.doc .tableblock pre { + white-space: pre-wrap +} + +.doc .listingblock pre:not(.highlight), +.doc .literalblock pre, +.doc pre.highlight code { + background: #fafafa; + -webkit-box-shadow: inset 0 0 1.75px #e1e1e1; + box-shadow: inset 0 0 1.75px #e1e1e1; + display: block; + overflow-x: auto; + padding: .875em +} + +.doc .listingblock>.content { + position: relative +} + +.doc .source-toolbox { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + visibility: hidden; + position: absolute; + top: .25rem; + right: .5rem; + color: grey; + font-family: Roboto, sans-serif; + font-size: .72222rem; + line-height: 1; + white-space: nowrap; + z-index: 1 +} + +.doc .listingblock:hover .source-toolbox { + visibility: visible +} + +.doc .source-toolbox .source-lang { + text-transform: uppercase; + letter-spacing: .075em +} + +.doc .source-toolbox>:not(:last-child)::after { + content: "|"; + letter-spacing: 0; + padding: 0 1ch +} + +.doc .source-toolbox .copy-button { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + background: none; + border: none; + color: inherit; + outline: none; + padding: 0; + font-size: inherit; + line-height: inherit; + width: 1em; + height: 1em +} + +.doc .source-toolbox .copy-icon { + -webkit-box-flex: 0; + -ms-flex: none; + flex: none; + width: inherit; + height: inherit +} + +.doc .source-toolbox img.copy-icon { + -webkit-filter: invert(50.2%); + filter: invert(50.2%) +} + +.doc .source-toolbox svg.copy-icon { + fill: currentColor +} + +.doc .source-toolbox .copy-toast { + -webkit-box-flex: 0; + -ms-flex: none; + flex: none; + position: relative; + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + margin-top: 1em; + background-color: #333; + border-radius: .25em; + padding: .5em; + color: #fff; + cursor: auto; + opacity: 0; + -webkit-transition: opacity .5s ease .5s; + transition: opacity .5s ease .5s +} + +.doc .source-toolbox .copy-toast::after { + content: ""; + position: absolute; + top: 0; + width: 1em; + height: 1em; + border: .55em solid transparent; + border-left-color: #333; + -webkit-transform: rotate(-90deg) translateX(50%) translateY(50%); + transform: rotate(-90deg) translateX(50%) translateY(50%); + -webkit-transform-origin: left; + transform-origin: left +} + +.doc .source-toolbox .copy-button.clicked .copy-toast { + opacity: 1; + -webkit-transition: none; + transition: none +} + +.doc .language-console .hljs-meta { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none +} + +.doc .dlist dt { + font-style: italic +} + +.doc .dlist dd { + margin: 0 0 .25rem 1.5rem +} + +.doc .dlist dd:last-of-type { + margin-bottom: 0 +} + +.doc td.hdlist1, +.doc td.hdlist2 { + padding: .5rem 0 0; + vertical-align: top +} + +.doc tr:first-child>.hdlist1, +.doc tr:first-child>.hdlist2 { + padding-top: 0 +} + +.doc td.hdlist1 { + font-weight: 500; + padding-right: .25rem +} + +.doc td.hdlist2 { + padding-left: .25rem +} + +.doc .colist { + font-size: .88889rem; + margin: .25rem 0 -.25rem +} + +.doc .colist>table>tbody>tr>:first-child, +.doc .colist>table>tr>:first-child { + padding: .25em .5rem 0; + vertical-align: top +} + +.doc .colist>table>tbody>tr>:last-child, +.doc .colist>table>tr>:last-child { + padding: .25rem 0 +} + +.doc .conum[data-value] { + border: 1px solid; + border-radius: 100%; + display: inline-block; + font-family: Roboto, sans-serif; + font-size: .75rem; + font-style: normal; + line-height: 1.2; + text-align: center; + width: 1.25em; + height: 1.25em; + letter-spacing: -.25ex; + text-indent: -.25ex +} + +.doc .conum[data-value]::after { + content: attr(data-value) +} + +.doc .conum[data-value]+b { + display: none +} + +.doc hr { + border: solid #e1e1e1; + border-width: 2px 0 0; + height: 0 +} + +.doc b.button { + white-space: nowrap +} + +.doc b.button::before { + content: "["; + padding-right: .25em +} + +.doc b.button::after { + content: "]"; + padding-left: .25em +} + +.doc kbd { + display: inline-block; + font-size: .66667rem; + background: #fafafa; + border: 1px solid #c1c1c1; + border-radius: .25em; + -webkit-box-shadow: 0 1px 0 #c1c1c1, 0 0 0 .1em #fff inset; + box-shadow: 0 1px 0 #c1c1c1, inset 0 0 0 .1em #fff; + padding: .25em .5em; + vertical-align: text-bottom; + white-space: nowrap +} + +.doc .keyseq, +.doc kbd { + line-height: 1 +} + +.doc .keyseq { + font-size: .88889rem +} + +.doc .keyseq kbd { + margin: 0 .125em +} + +.doc .keyseq kbd:first-child { + margin-left: 0 +} + +.doc .keyseq kbd:last-child { + margin-right: 0 +} + +.doc .menuseq, +.doc .path { + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none +} + +.doc .menuseq i.caret::before { + content: "\203a"; + font-size: 1.1em; + font-weight: 500; + line-height: .90909 +} + +.doc :not(pre).nowrap { + white-space: nowrap +} + +.doc .nobreak { + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + word-wrap: normal +} + +#footnotes { + font-size: .85em; + line-height: 1.5; + margin: 2rem -.5rem 0 +} + +.doc td.tableblock>.content #footnotes { + margin: 2rem 0 0 +} + +#footnotes hr { + border-top-width: 1px; + margin-top: 0; + width: 20% +} + +#footnotes .footnote { + margin: .5em 0 0 1em +} + +#footnotes .footnote+.footnote { + margin-top: .25em +} + +#footnotes .footnote>a:first-of-type { + display: inline-block; + margin-left: -2em; + text-align: right; + width: 1.5em +} + +nav.pagination { + border-top: 1px solid #e1e1e1; + line-height: 1; + margin: 2rem -1rem -1rem; + padding: .75rem 1rem 0 +} + +nav.pagination, +nav.pagination span { + display: -webkit-box; + display: -ms-flexbox; + display: flex +} + +nav.pagination span { + -webkit-box-flex: 50%; + -ms-flex: 50%; + flex: 50%; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column +} + +nav.pagination .prev { + padding-right: .5rem +} + +nav.pagination .next { + margin-left: auto; + padding-left: .5rem; + text-align: right +} + +nav.pagination span::before { + color: #8e8e8e; + font-size: .75em; + padding-bottom: .1em +} + +nav.pagination .prev::before { + content: "Prev" +} + +nav.pagination .next::before { + content: "Next" +} + +nav.pagination a { + font-weight: 500; + line-height: 1.3; + position: relative +} + +nav.pagination a::after, +nav.pagination a::before { + color: #8e8e8e; + font-weight: 400; + font-size: 1.5em; + line-height: .75; + position: absolute; + top: 0; + width: 1rem +} + +nav.pagination .prev a::before { + content: "\2039"; + -webkit-transform: translateX(-100%); + transform: translateX(-100%) +} + +nav.pagination .next a::after { + content: "\203a" +} + +html.is-clipped--navbar { + overflow-y: hidden +} + +body { + padding-top: 3.5rem +} + +.navbar { + background: #191919; + color: #fff; + font-size: .88889rem; + height: 3.5rem; + position: fixed; + top: 0; + width: 100%; + z-index: 4 +} + +.navbar a { + text-decoration: none +} + +.navbar-brand { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-flex: 1; + -ms-flex: auto; + flex: auto; + padding-left: 1rem +} + +.navbar-brand .navbar-item { + color: #fff +} + +.navbar-brand .navbar-item:first-child { + -ms-flex-item-align: center; + align-self: center; + padding: 0; + font-size: 1.22222rem; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + line-height: 1 +} + +.navbar-brand .navbar-item:first-child a { + color: inherit; + word-wrap: normal +} + +.navbar-brand .navbar-item:first-child :not(:last-child) { + padding-right: .375rem +} + +.navbar-brand .navbar-item.search { + -webkit-box-flex: 1; + -ms-flex: auto; + flex: auto; + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end +} + +#search-input { + color: #333; + font-family: inherit; + font-size: .95rem; + width: 150px; + border: 1px solid #dbdbdb; + border-radius: .1em; + line-height: 1.5; + padding: 0 .25em +} + +#search-input:disabled { + background-color: #dbdbdb; + cursor: not-allowed; + pointer-events: all !important +} + +#search-input:disabled::-webkit-input-placeholder { + color: #4c4c4c +} + +#search-input:disabled::-moz-placeholder { + color: #4c4c4c +} + +#search-input:disabled:-ms-input-placeholder { + color: #4c4c4c +} + +#search-input:disabled::-ms-input-placeholder { + color: #4c4c4c +} + +#search-input:disabled::placeholder { + color: #4c4c4c +} + +#search-input:focus { + outline: none +} + +.navbar-burger { + background: none; + border: none; + outline: none; + line-height: 1; + position: relative; + width: 3rem; + padding: 0; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + margin-left: auto; + min-width: 0 +} + +.navbar-burger span { + background-color: #fff; + height: 1.5px; + width: 1rem +} + +.navbar-burger:not(.is-active) span { + -webkit-transition: opacity 0s .25s, margin-top .25s ease-out .25s, -webkit-transform .25s ease-out; + transition: opacity 0s .25s, margin-top .25s ease-out .25s, -webkit-transform .25s ease-out; + transition: transform .25s ease-out, opacity 0s .25s, margin-top .25s ease-out .25s; + transition: transform .25s ease-out, opacity 0s .25s, margin-top .25s ease-out .25s, -webkit-transform .25s ease-out +} + +.navbar-burger span+span { + margin-top: .25rem +} + +.navbar-burger.is-active span+span { + margin-top: -1.5px +} + +.navbar-burger.is-active span:first-child { + -webkit-transform: rotate(45deg); + transform: rotate(45deg) +} + +.navbar-burger.is-active span:nth-child(2) { + opacity: 0 +} + +.navbar-burger.is-active span:nth-child(3) { + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg) +} + +.navbar-item, +.navbar-link { + color: #222; + display: block; + line-height: 1.6; + padding: .5rem 1rem +} + +.navbar-item.has-dropdown { + padding: 0 +} + +.navbar-item .icon { + width: 1.25rem; + height: 1.25rem; + display: block +} + +.navbar-item .icon img, +.navbar-item .icon svg { + fill: currentColor; + width: inherit; + height: inherit +} + +.navbar-link { + padding-right: 2.5em +} + +.navbar-dropdown .navbar-item { + padding-left: 1.5rem; + padding-right: 1.5rem +} + +.navbar-dropdown .navbar-item.has-label { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between +} + +.navbar-dropdown .navbar-item small { + color: #8e8e8e; + font-size: .66667rem +} + +.navbar-divider { + background-color: #e1e1e1; + border: none; + height: 1px; + margin: .25rem 0 +} + +.navbar .button { + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + background: #fff; + border: 1px solid #e1e1e1; + border-radius: .15rem; + height: 1.75rem; + color: #222; + padding: 0 .75em; + white-space: nowrap +} + +@media screen and (max-width:768.5px) { + .navbar-brand .navbar-item.search { + padding-left: 0; + padding-right: 0 + } +} + +@media screen and (min-width:769px) { + #search-input { + width: 200px + } +} + +@media screen and (max-width:1023.5px) { + .navbar-brand { + height: inherit + } + + .navbar-brand .navbar-item { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + display: -webkit-box; + display: -ms-flexbox; + display: flex + } + + .navbar-menu { + background: #fff; + -webkit-box-shadow: 0 8px 16px rgba(10, 10, 10, .1); + box-shadow: 0 8px 16px rgba(10, 10, 10, .1); + max-height: calc(100vh - 3.5rem); + overflow-y: auto; + -ms-scroll-chaining: none; + overscroll-behavior: none; + padding: .5rem 0 + } + + .navbar-menu:not(.is-active) { + display: none + } + + .navbar-menu .navbar-link:hover, + .navbar-menu a.navbar-item:hover { + background: #f5f5f5 + } +} + +@media screen and (min-width:1024px) { + .navbar-burger { + display: none + } + + .navbar, + .navbar-end, + .navbar-item, + .navbar-link, + .navbar-menu { + display: -webkit-box; + display: -ms-flexbox; + display: flex + } + + .navbar-item, + .navbar-link { + position: relative; + -webkit-box-flex: 0; + -ms-flex: none; + flex: none + } + + .navbar-item:not(.has-dropdown), + .navbar-link { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center + } + + .navbar-item.is-hoverable:hover .navbar-dropdown { + display: block + } + + .navbar-link::after { + border-width: 0 0 1px 1px; + border-style: solid; + content: ""; + display: block; + height: .5em; + pointer-events: none; + position: absolute; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + width: .5em; + margin-top: -.375em; + right: 1.125em; + top: 50% + } + + .navbar-end .navbar-link, + .navbar-end>.navbar-item { + color: #fff + } + + .navbar-end .navbar-item.has-dropdown:hover .navbar-link, + .navbar-end .navbar-link:hover, + .navbar-end>a.navbar-item:hover { + background: #000; + color: #fff + } + + .navbar-end .navbar-link::after { + border-color: currentColor + } + + .navbar-dropdown { + background: #fff; + border: 1px solid #e1e1e1; + border-top: none; + border-radius: 0 0 .25rem .25rem; + display: none; + top: 100%; + left: 0; + min-width: 100%; + position: absolute + } + + .navbar-dropdown .navbar-item { + padding: .5rem 3rem .5rem 1rem; + white-space: nowrap + } + + .navbar-dropdown .navbar-item small { + position: relative; + right: -2rem + } + + .navbar-dropdown .navbar-item:last-child { + border-radius: inherit + } + + .navbar-dropdown.is-right { + left: auto; + right: 0 + } + + .navbar-dropdown a.navbar-item:hover { + background: #f5f5f5 + } +} + +footer.footer { + background-color: #e1e1e1; + color: #5d5d5d; + font-size: .83333rem; + line-height: 1.6; + padding: 1.5rem +} + +.footer p { + margin: .5rem 0 +} + +.footer a { + color: #191919 +} + +/*! Adapted from the GitHub style by Vasily Polovnyov */ +.hljs-comment, +.hljs-quote { + color: #998; + font-style: italic +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: #333; + font-weight: 500 +} + +.hljs-literal, +.hljs-number, +.hljs-tag .hljs-attr, +.hljs-template-variable, +.hljs-variable { + color: teal +} + +.hljs-doctag, +.hljs-string { + color: #d14 +} + +.hljs-section, +.hljs-selector-id, +.hljs-title { + color: #900; + font-weight: 500 +} + +.hljs-subst { + font-weight: 400 +} + +.hljs-class .hljs-title, +.hljs-type { + color: #458; + font-weight: 500 +} + +.hljs-attribute, +.hljs-name, +.hljs-tag { + color: navy; + font-weight: 400 +} + +.hljs-link, +.hljs-regexp { + color: #009926 +} + +.hljs-bullet, +.hljs-symbol { + color: #990073 +} + +.hljs-built_in, +.hljs-builtin-name { + color: #0086b3 +} + +.hljs-meta { + color: #999; + font-weight: 500 +} + +.hljs-deletion { + background: #fdd +} + +.hljs-addition { + background: #dfd +} + +.hljs-emphasis { + font-style: italic +} + +.hljs-strong { + font-weight: 500 +} + +@page { + margin: .5in +} + +@media print { + .hide-for-print { + display: none !important + } + + html { + font-size: .9375em + } + + a { + color: inherit !important; + text-decoration: underline + } + + a.bare, + a[href^="#"], + a[href^="mailto:"] { + text-decoration: none + } + + img, + object, + svg, + tr { + page-break-inside: avoid + } + + thead { + display: table-header-group + } + + pre { + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + white-space: pre-wrap + } + + body { + padding-top: 2rem + } + + .navbar { + background: none; + color: inherit; + position: absolute + } + + .navbar * { + color: inherit !important + } + + .nav-container, + .navbar>:not(.navbar-brand), + .toolbar, + aside.toc, + nav.pagination { + display: none + } + + .doc { + color: inherit; + margin: auto; + max-width: none; + padding-bottom: 2rem + } + + .doc .admonitionblock td.icon { + -webkit-print-color-adjust: exact; + color-adjust: exact + } + + .doc .listingblock code[data-lang]::before { + display: block + } + + footer.footer { + background: none; + border-top: 1px solid #e1e1e1; + color: #8e8e8e; + padding: .25rem .5rem 0 + } + + .footer * { + color: inherit + } +} \ No newline at end of file diff --git a/pr-preview/pr-59/_/font/roboto-latin-400-italic.woff b/pr-preview/pr-59/_/font/roboto-latin-400-italic.woff new file mode 100644 index 0000000..ebee16b Binary files /dev/null and b/pr-preview/pr-59/_/font/roboto-latin-400-italic.woff differ diff --git a/pr-preview/pr-59/_/font/roboto-latin-400-italic.woff2 b/pr-preview/pr-59/_/font/roboto-latin-400-italic.woff2 new file mode 100644 index 0000000..e1b7a79 Binary files /dev/null and b/pr-preview/pr-59/_/font/roboto-latin-400-italic.woff2 differ diff --git a/pr-preview/pr-59/_/font/roboto-latin-400-normal.woff b/pr-preview/pr-59/_/font/roboto-latin-400-normal.woff new file mode 100644 index 0000000..9eaa94f Binary files /dev/null and b/pr-preview/pr-59/_/font/roboto-latin-400-normal.woff differ diff --git a/pr-preview/pr-59/_/font/roboto-latin-400-normal.woff2 b/pr-preview/pr-59/_/font/roboto-latin-400-normal.woff2 new file mode 100644 index 0000000..020729e Binary files /dev/null and b/pr-preview/pr-59/_/font/roboto-latin-400-normal.woff2 differ diff --git a/pr-preview/pr-59/_/font/roboto-latin-500-italic.woff b/pr-preview/pr-59/_/font/roboto-latin-500-italic.woff new file mode 100644 index 0000000..b6ad1c5 Binary files /dev/null and b/pr-preview/pr-59/_/font/roboto-latin-500-italic.woff differ diff --git a/pr-preview/pr-59/_/font/roboto-latin-500-italic.woff2 b/pr-preview/pr-59/_/font/roboto-latin-500-italic.woff2 new file mode 100644 index 0000000..ae1933f Binary files /dev/null and b/pr-preview/pr-59/_/font/roboto-latin-500-italic.woff2 differ diff --git a/pr-preview/pr-59/_/font/roboto-latin-500-normal.woff b/pr-preview/pr-59/_/font/roboto-latin-500-normal.woff new file mode 100644 index 0000000..d39bb52 Binary files /dev/null and b/pr-preview/pr-59/_/font/roboto-latin-500-normal.woff differ diff --git a/pr-preview/pr-59/_/font/roboto-latin-500-normal.woff2 b/pr-preview/pr-59/_/font/roboto-latin-500-normal.woff2 new file mode 100644 index 0000000..29342a8 Binary files /dev/null and b/pr-preview/pr-59/_/font/roboto-latin-500-normal.woff2 differ diff --git a/pr-preview/pr-59/_/font/roboto-mono-latin-400-normal.woff b/pr-preview/pr-59/_/font/roboto-mono-latin-400-normal.woff new file mode 100644 index 0000000..be3eb4c Binary files /dev/null and b/pr-preview/pr-59/_/font/roboto-mono-latin-400-normal.woff differ diff --git a/pr-preview/pr-59/_/font/roboto-mono-latin-400-normal.woff2 b/pr-preview/pr-59/_/font/roboto-mono-latin-400-normal.woff2 new file mode 100644 index 0000000..f8894ba Binary files /dev/null and b/pr-preview/pr-59/_/font/roboto-mono-latin-400-normal.woff2 differ diff --git a/pr-preview/pr-59/_/font/roboto-mono-latin-500-normal.woff b/pr-preview/pr-59/_/font/roboto-mono-latin-500-normal.woff new file mode 100644 index 0000000..43ca6a1 Binary files /dev/null and b/pr-preview/pr-59/_/font/roboto-mono-latin-500-normal.woff differ diff --git a/pr-preview/pr-59/_/font/roboto-mono-latin-500-normal.woff2 b/pr-preview/pr-59/_/font/roboto-mono-latin-500-normal.woff2 new file mode 100644 index 0000000..b4f2bf8 Binary files /dev/null and b/pr-preview/pr-59/_/font/roboto-mono-latin-500-normal.woff2 differ diff --git a/pr-preview/pr-59/_/img/back.svg b/pr-preview/pr-59/_/img/back.svg new file mode 100644 index 0000000..bf7d30e --- /dev/null +++ b/pr-preview/pr-59/_/img/back.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pr-preview/pr-59/_/img/caret.svg b/pr-preview/pr-59/_/img/caret.svg new file mode 100644 index 0000000..1af41bc --- /dev/null +++ b/pr-preview/pr-59/_/img/caret.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pr-preview/pr-59/_/img/chevron.svg b/pr-preview/pr-59/_/img/chevron.svg new file mode 100644 index 0000000..40e962a --- /dev/null +++ b/pr-preview/pr-59/_/img/chevron.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pr-preview/pr-59/_/img/hat-logo.png b/pr-preview/pr-59/_/img/hat-logo.png new file mode 100644 index 0000000..47128f4 Binary files /dev/null and b/pr-preview/pr-59/_/img/hat-logo.png differ diff --git a/pr-preview/pr-59/_/img/home-o.svg b/pr-preview/pr-59/_/img/home-o.svg new file mode 100644 index 0000000..95d193b --- /dev/null +++ b/pr-preview/pr-59/_/img/home-o.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pr-preview/pr-59/_/img/home.svg b/pr-preview/pr-59/_/img/home.svg new file mode 100644 index 0000000..4e96b35 --- /dev/null +++ b/pr-preview/pr-59/_/img/home.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pr-preview/pr-59/_/img/menu.svg b/pr-preview/pr-59/_/img/menu.svg new file mode 100644 index 0000000..8b43b2e --- /dev/null +++ b/pr-preview/pr-59/_/img/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pr-preview/pr-59/_/img/octicons-16.svg b/pr-preview/pr-59/_/img/octicons-16.svg new file mode 100644 index 0000000..e3b4e20 --- /dev/null +++ b/pr-preview/pr-59/_/img/octicons-16.svg @@ -0,0 +1 @@ +Octicons v11.2.0 by GitHub - https://primer.style/octicons/ - License: MIT \ No newline at end of file diff --git a/pr-preview/pr-59/_/img/redhat-logo.png b/pr-preview/pr-59/_/img/redhat-logo.png new file mode 100644 index 0000000..a9cf250 Binary files /dev/null and b/pr-preview/pr-59/_/img/redhat-logo.png differ diff --git a/pr-preview/pr-59/_/img/rhl-logo-red.png b/pr-preview/pr-59/_/img/rhl-logo-red.png new file mode 100644 index 0000000..954ab68 Binary files /dev/null and b/pr-preview/pr-59/_/img/rhl-logo-red.png differ diff --git a/pr-preview/pr-59/_/js/site.js b/pr-preview/pr-59/_/js/site.js new file mode 100644 index 0000000..74a8b5f --- /dev/null +++ b/pr-preview/pr-59/_/js/site.js @@ -0,0 +1,6 @@ +!function(){"use strict";var e,o,r,s=/^sect(\d)$/,i=document.querySelector(".nav-container"),a=document.querySelector(".nav-toggle"),c=i.querySelector(".nav"),l=(a.addEventListener("click",function(e){if(a.classList.contains("is-active"))return u(e);v(e);var e=document.documentElement,t=(e.classList.add("is-clipped--nav"),a.classList.add("is-active"),i.classList.add("is-active"),c.getBoundingClientRect()),n=window.innerHeight-Math.round(t.top);Math.round(t.height)!==n&&(c.style.height=n+"px");e.addEventListener("click",u)}),i.addEventListener("click",v),i.querySelector("[data-panel=menu]"));function t(){var e,t,n=window.location.hash;if(n&&(n.indexOf("%")&&(n=decodeURIComponent(n)),!(e=l.querySelector('.nav-link[href="'+n+'"]')))){n=document.getElementById(n.slice(1));if(n)for(var i=n,a=document.querySelector("article.doc");(i=i.parentNode)&&i!==a;){var c=i.id;if((c=c||(c=s.test(i.className))&&(i.firstElementChild||{}).id)&&(e=l.querySelector('.nav-link[href="#'+c+'"]')))break}}if(e)t=e.parentNode;else{if(!r)return;e=(t=r).querySelector(".nav-link")}t!==o&&(h(l,".nav-item.is-active").forEach(function(e){e.classList.remove("is-active","is-current-path","is-current-page")}),t.classList.add("is-current-page"),d(o=t),p(l,e))}function d(e){for(var t,n=e.parentNode;!(t=n.classList).contains("nav-menu");)"LI"===n.tagName&&t.contains("nav-item")&&t.add("is-active","is-current-path"),n=n.parentNode;e.classList.add("is-active")}function n(){var e,t,n,i;this.classList.toggle("is-active")&&(e=parseFloat(window.getComputedStyle(this).marginTop),t=this.getBoundingClientRect(),n=l.getBoundingClientRect(),0<(i=(t.bottom-n.top-n.height+e).toFixed()))&&(l.scrollTop+=Math.min((t.top-n.top-e).toFixed(),i))}function u(e){v(e);e=document.documentElement;e.classList.remove("is-clipped--nav"),a.classList.remove("is-active"),i.classList.remove("is-active"),e.removeEventListener("click",u)}function v(e){e.stopPropagation()}function p(e,t){var n=e.getBoundingClientRect(),i=n.height,a=window.getComputedStyle(c);"sticky"===a.position&&(i-=n.top-parseFloat(a.top)),e.scrollTop=Math.max(0,.5*(t.getBoundingClientRect().height-i)+t.offsetTop)}function h(e,t){return[].slice.call(e.querySelectorAll(t))}l&&(e=i.querySelector("[data-panel=explore]"),o=l.querySelector(".is-current-page"),(r=o)?(d(o),p(l,o.querySelector(".nav-link"))):l.scrollTop=0,h(l,".nav-item-toggle").forEach(function(e){var t=e.parentElement,e=(e.addEventListener("click",n.bind(t)),function(e,t){e=e.nextElementSibling;return(!e||!t||e[e.matches?"matches":"msMatchesSelector"](t))&&e}(e,".nav-text"));e&&(e.style.cursor="pointer",e.addEventListener("click",n.bind(t)))}),e&&e.querySelector(".context").addEventListener("click",function(){h(c,"[data-panel]").forEach(function(e){e.classList.toggle("is-active")})}),l.addEventListener("mousedown",function(e){1":"")+".sect"+c);r.push("h"+(i+1)+"[id]")}else r.push("h1[id].sect0");n.push(r.join(">"))}m=n.join(","),f=d.parentNode;var a,s=[].slice.call((f||document).querySelectorAll(m));if(!s.length)return e.parentNode.removeChild(e);var l={},u=s.reduce(function(e,t){var o=document.createElement("a"),n=(o.textContent=t.textContent,l[o.href="#"+t.id]=o,document.createElement("li"));return n.dataset.level=parseInt(t.nodeName.slice(1),10)-1,n.appendChild(o),e.appendChild(n),e},document.createElement("ul")),f=e.querySelector(".toc-menu"),m=(f||((f=document.createElement("div")).className="toc-menu"),document.createElement("h3")),e=(m.textContent=e.dataset.title||"Contents",f.appendChild(m),f.appendChild(u),!document.getElementById("toc")&&d.querySelector("h1.page ~ :not(.is-before-toc)"));e&&((m=document.createElement("aside")).className="toc embedded",m.appendChild(f.cloneNode(!0)),e.parentNode.insertBefore(m,e)),window.addEventListener("load",function(){p(),window.addEventListener("scroll",p)})}}function p(){var n,i,t,e=window.pageYOffset,o=1.15*h(document.documentElement,"fontSize"),r=d.offsetTop;e&&window.innerHeight+e+2>=document.documentElement.scrollHeight?(a=Array.isArray(a)?a:Array(a||0),n=[],i=s.length-1,s.forEach(function(e,t){var o="#"+e.id;t===i||e.getBoundingClientRect().top+h(e,"paddingTop")>r?(n.push(o),a.indexOf(o)<0&&l[o].classList.add("is-active")):~a.indexOf(o)&&l[a.shift()].classList.remove("is-active")}),u.scrollTop=u.scrollHeight-u.offsetHeight,a=1r)return!0;t="#"+e.id}),t?t!==a&&(a&&l[a].classList.remove("is-active"),(e=l[t]).classList.add("is-active"),u.scrollHeight>u.offsetHeight&&(u.scrollTop=Math.max(0,e.offsetTop+e.offsetHeight-u.offsetHeight)),a=t):a&&(l[a].classList.remove("is-active"),a=void 0))}function h(e,t){return parseFloat(window.getComputedStyle(e)[t])}}(); +!function(){"use strict";var o=document.querySelector("article.doc"),t=document.querySelector(".toolbar");function i(e){return e&&(~e.indexOf("%")?decodeURIComponent(e):e).slice(1)}function r(e){if(e){if(e.altKey||e.ctrlKey)return;window.location.hash="#"+this.id,e.preventDefault()}window.scrollTo(0,function e(t,n){return o.contains(t)?e(t.offsetParent,t.offsetTop+n):n}(this,0)-t.getBoundingClientRect().bottom)}window.addEventListener("load",function e(t){var n;(n=i(window.location.hash))&&(n=document.getElementById(n))&&(r.bind(n)(),setTimeout(r.bind(n),0)),window.removeEventListener("load",e)}),Array.prototype.slice.call(document.querySelectorAll('a[href^="#"]')).forEach(function(e){var t;(t=i(e.hash))&&(t=document.getElementById(t))&&e.addEventListener("click",r.bind(t))})}(); +!function(){"use strict";var t,e=document.querySelector(".page-versions .version-menu-toggle");e&&(t=document.querySelector(".page-versions"),e.addEventListener("click",function(e){t.classList.toggle("is-active"),e.stopPropagation()}),document.documentElement.addEventListener("click",function(){t.classList.remove("is-active")}))}(); +!function(){"use strict";var t=document.querySelector(".navbar-burger");t&&t.addEventListener("click",function(t){t.stopPropagation(),document.documentElement.classList.toggle("is-clipped--navbar"),this.classList.toggle("is-active");t=document.getElementById(this.dataset.target);{var e;t.classList.toggle("is-active")&&(t.style.maxHeight="",e=window.innerHeight-Math.round(t.getBoundingClientRect().top),parseInt(window.getComputedStyle(t).maxHeight,10)!==e)&&(t.style.maxHeight=e+"px")}}.bind(t))}(); +!function(){"use strict";var o=/^\$ (\S[^\\\n]*(\\\n(?!\$ )[^\\\n]*)*)(?=\n|$)/gm,s=/( ) *\\\n *|\\\n( ?) */g,l=/ +$/gm,e=(document.getElementById("site-script")||{dataset:{}}).dataset,d=null==e.uiRootPath?".":e.uiRootPath,r=e.svgAs,p=window.navigator.clipboard;[].slice.call(document.querySelectorAll(".doc pre.highlight, .doc .literalblock pre")).forEach(function(e){var t,n,a,c;if(e.classList.contains("highlight"))(i=(t=e.querySelector("code")).dataset.lang)&&"console"!==i&&((a=document.createElement("span")).className="source-lang",a.appendChild(document.createTextNode(i)));else{if(!e.innerText.startsWith("$ "))return;var i=e.parentNode.parentNode;i.classList.remove("literalblock"),i.classList.add("listingblock"),e.classList.add("highlightjs","highlight"),(t=document.createElement("code")).className="language-console hljs",t.dataset.lang="console",t.appendChild(e.firstChild),e.appendChild(t)}(i=document.createElement("div")).className="source-toolbox",a&&i.appendChild(a),p&&((n=document.createElement("button")).className="copy-button",n.setAttribute("title","Copy to clipboard"),"svg"===r?((a=document.createElementNS("http://www.w3.org/2000/svg","svg")).setAttribute("class","copy-icon"),(c=document.createElementNS("http://www.w3.org/2000/svg","use")).setAttribute("href",d+"/img/octicons-16.svg#icon-clippy"),a.appendChild(c),n.appendChild(a)):((c=document.createElement("img")).src=d+"/img/octicons-16.svg#view-clippy",c.alt="copy icon",c.className="copy-icon",n.appendChild(c)),(a=document.createElement("span")).className="copy-toast",a.appendChild(document.createTextNode("Copied!")),n.appendChild(a),i.appendChild(n)),e.parentNode.appendChild(i),n&&n.addEventListener("click",function(e){var t=e.innerText.replace(l,"");"console"===e.dataset.lang&&t.startsWith("$ ")&&(t=function(e){var t,n=[];for(;t=o.exec(e);)n.push(t[1].replace(s,"$1$2"));return n.join(" && ")}(t));window.navigator.clipboard.writeText(t).then(function(){this.classList.add("clicked"),this.offsetHeight,this.classList.remove("clicked")}.bind(this),function(){})}.bind(n,t))})}(); \ No newline at end of file diff --git a/pr-preview/pr-59/_/js/vendor/highlight.js b/pr-preview/pr-59/_/js/vendor/highlight.js new file mode 100644 index 0000000..f0be714 --- /dev/null +++ b/pr-preview/pr-59/_/js/vendor/highlight.js @@ -0,0 +1 @@ +!function(){function e(e){return{aliases:["adoc"],contains:[e.COMMENT("^/{4,}\\n","\\n/{4,}$",{relevance:10}),e.COMMENT("^//","$",{relevance:0}),{className:"title",begin:"^\\.\\w.*$"},{begin:"^[=\\*]{4,}\\n",end:"\\n^[=\\*]{4,}$",relevance:10},{className:"section",relevance:10,variants:[{begin:"^(={1,5}) .+?( \\1)?$"},{begin:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$"}]},{className:"meta",begin:"^:.+?:",end:"\\s",excludeEnd:!0,relevance:10},{className:"meta",begin:"^\\[.+?\\]$",relevance:0},{className:"quote",begin:"^_{4,}\\n",end:"\\n_{4,}$",relevance:10},{className:"code",begin:"^[\\-\\.]{4,}\\n",end:"\\n[\\-\\.]{4,}$",relevance:10},{begin:"^\\+{4,}\\n",end:"\\n\\+{4,}$",contains:[{begin:"<",end:">",subLanguage:"xml",relevance:0}],relevance:10},{className:"bullet",begin:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{className:"symbol",begin:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",relevance:10},{className:"strong",begin:"\\B\\*(?![\\*\\s])",end:"(\\n{2}|\\*)",contains:[{begin:"\\\\*\\w",relevance:0}]},{className:"emphasis",begin:"\\B'(?!['\\s])",end:"(\\n{2}|')",contains:[{begin:"\\\\'\\w",relevance:0}],relevance:0},{className:"emphasis",begin:"_(?![_\\s])",end:"(\\n{2}|_)",relevance:0},{className:"string",variants:[{begin:"``.+?''"},{begin:"`.+?'"}]},{className:"code",begin:"(`.+?`|\\+.+?\\+)",relevance:0},{className:"code",begin:"^[ \\t]",end:"$",relevance:0},{begin:"^'{3,}[ \\t]*$",relevance:10},{begin:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",returnBegin:!0,contains:[{begin:"(link|image:?):",relevance:0},{className:"link",begin:"\\w",end:"[^\\[]+",relevance:0},{className:"string",begin:"\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0,relevance:0}],relevance:10}]}}function n(e){var n={className:"variable",variants:[{begin:/\$[\w\d#@][\w\d_]*/},{begin:/\$\{(.*?)}/}]},a={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,n,{className:"variable",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]}]};return{aliases:["sh","zsh"],lexemes:/\b-?[a-z\._]+\b/,keywords:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"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 autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},contains:[{className:"meta",begin:/^#![^\n]+sh\s*$/,relevance:10},{className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0},e.HASH_COMMENT_MODE,a,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},n]}}function a(e){var n={begin:u="["+(u="a-zA-Z_\\-!.?+*=<>&#'")+"]["+u+"0-9/;:]*",relevance:0},a={className:"number",begin:"[-+]?\\d+(\\.\\d+)?",relevance:0},t=e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),i=e.COMMENT(";","$",{relevance:0}),s={className:"literal",begin:/\b(true|false|nil)\b/},r={begin:"[\\[\\{]",end:"[\\]\\}]"},l={className:"comment",begin:"\\^"+u},o=e.COMMENT("\\^\\{","\\}"),c={className:"symbol",begin:"[:]{1,2}"+u},d={begin:"\\(",end:"\\)"},g={endsWithParent:!0,relevance:0},u={keywords:{"builtin-name":"def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},lexemes:u,className:"name",begin:u,starts:g},n=[d,t,l,o,i,c,r,a,s,n];return d.contains=[e.COMMENT("comment",""),u,g],g.contains=n,r.contains=n,o.contains=[r],{aliases:["clj"],illegal:/\S/,contains:[d,t,l,o,i,c,r,a,s]}}function t(e){function n(e){return"(?:"+e+")?"}var a="decltype\\(auto\\)",t="[a-zA-Z_]\\w*::",i={className:"keyword",begin:"\\b[a-z\\d_]*_t\\b"},s={className:"string",variants:[{begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",end:"'",illegal:"."},{begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\((?:.|\n)*?\)\1"/}]},r={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},l={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{"meta-keyword":"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},e.inherit(s,{className:"meta-string"}),{className:"meta-string",begin:/<.*?>/,end:/$/,illegal:"\\n"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},o={className:"title",begin:n(t)+e.IDENT_RE,relevance:0},t=n(t)+e.IDENT_RE+"\\s*\\(",c={keyword:"int float while private char char8_t char16_t char32_t catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid wchar_tshort reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignas alignof constexpr consteval constinit decltype concept co_await co_return co_yield requires noexcept static_assert thread_local restrict final override atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq",built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr _Bool complex _Complex imaginary _Imaginary",literal:"true false nullptr NULL"},d=[i,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,r,s],g={variants:[{begin:/=/,end:/;/},{begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],keywords:c,contains:d.concat([{begin:/\(/,end:/\)/,keywords:c,contains:d.concat(["self"]),relevance:0}]),relevance:0},a={className:"function",begin:"((decltype\\(auto\\)|(?:[a-zA-Z_]\\w*::)?[a-zA-Z_]\\w*(?:<.*?>)?)[\\*&\\s]+)+"+t,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:c,illegal:/[^\w\s\*&:<>]/,contains:[{begin:a,keywords:c,relevance:0},{begin:t,returnBegin:!0,contains:[o],relevance:0},{className:"params",begin:/\(/,end:/\)/,keywords:c,relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s,r,i,{begin:/\(/,end:/\)/,keywords:c,relevance:0,contains:["self",e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s,r,i]}]},i,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,l]};return{aliases:["c","cc","h","c++","h++","hpp","hh","hxx","cxx"],keywords:c,illegal:"",keywords:c,contains:["self",i]},{begin:e.IDENT_RE+"::",keywords:c},{className:"class",beginKeywords:"class struct",end:/[{;:]/,contains:[{begin://,contains:["self"]},e.TITLE_MODE]}]),exports:{preprocessor:l,strings:s,keywords:c}}}function i(e){var n={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let nameof on orderby partial remove select set value var when where yield",literal:"null false true"},a={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},t={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}]},i=e.inherit(t,{illegal:/\n/}),s={className:"subst",begin:"{",end:"}",keywords:n},r=e.inherit(s,{illegal:/\n/}),l={className:"string",begin:/\$"/,end:'"',illegal:/\n/,contains:[{begin:"{{"},{begin:"}}"},e.BACKSLASH_ESCAPE,r]},o={className:"string",begin:/\$@"/,end:'"',contains:[{begin:"{{"},{begin:"}}"},{begin:'""'},s]},c=e.inherit(o,{illegal:/\n/,contains:[{begin:"{{"},{begin:"}}"},{begin:'""'},r]}),s=(s.contains=[o,l,t,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE],r.contains=[c,l,i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{illegal:/\n/})],{variants:[o,l,t,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]}),r=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?";return{aliases:["csharp","c#"],keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0,contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{begin:"\x3c!--|--\x3e"},{begin:""}]}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#",end:"$",keywords:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},s,a,{beginKeywords:"class interface",end:/[{;=]/,illegal:/[^\s:,]/,contains:[e.TITLE_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace",end:/[{;=]/,illegal:/[^\s:]/,contains:[e.inherit(e.TITLE_MODE,{begin:"[a-zA-Z](\\.?\\w)*"}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta",begin:"^\\s*\\[",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{className:"meta-string",begin:/"/,end:/"/}]},{beginKeywords:"new return throw await else",relevance:0},{className:"function",begin:"("+r+"\\s+)+"+e.IDENT_RE+"\\s*\\(",returnBegin:!0,end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{begin:e.IDENT_RE+"\\s*\\(",returnBegin:!0,contains:[e.TITLE_MODE],relevance:0},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0,contains:[s,a,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]}]}}function s(e){var n={className:"attribute",begin:/\S/,end:":",excludeEnd:!0,starts:{endsWithParent:!0,excludeEnd:!0,contains:[{begin:/[\w-]+\(/,returnBegin:!0,contains:[{className:"built_in",begin:/[\w-]+/},{begin:/\(/,end:/\)/,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.CSS_NUMBER_MODE]}]},e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_BLOCK_COMMENT_MODE,{className:"number",begin:"#[0-9A-Fa-f]+"},{className:"meta",begin:"!important"}]}};return{case_insensitive:!0,illegal:/[=\/|'\$]/,contains:[e.C_BLOCK_COMMENT_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/},{className:"selector-class",begin:/\.[A-Za-z0-9_-]+/},{className:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},{className:"selector-pseudo",begin:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{begin:"@(page|font-face)",lexemes:"@[a-z-]+",keywords:"@page @font-face"},{begin:"@",end:"[{;]",illegal:/:/,returnBegin:!0,contains:[{className:"keyword",begin:/@\-?\w[\w]*(\-\w+)*/},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:"and or not only",contains:[{begin:/[a-z-]+:/,className:"attribute"},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.CSS_NUMBER_MODE]}]},{className:"selector-tag",begin:"[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0},{begin:"{",end:"}",illegal:/\S/,contains:[e.C_BLOCK_COMMENT_MODE,{begin:/(?:[A-Z\_\.\-]+|--[a-zA-Z0-9_-]+)\s*:/,returnBegin:!0,end:";",endsWithParent:!0,contains:[n]}]}]}}function r(e){return{aliases:["patch"],contains:[{className:"meta",relevance:10,variants:[{begin:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{begin:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{begin:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{className:"comment",variants:[{begin:/Index: /,end:/$/},{begin:/={3,}/,end:/$/},{begin:/^\-{3}/,end:/$/},{begin:/^\*{3} /,end:/$/},{begin:/^\+{3}/,end:/$/},{begin:/^\*{15}$/}]},{className:"addition",begin:"^\\+",end:"$"},{className:"deletion",begin:"^\\-",end:"$"},{className:"addition",begin:"^\\!",end:"$"}]}}function l(e){return{aliases:["docker"],case_insensitive:!0,keywords:"from maintainer expose env arg user onbuild stopsignal",contains:[e.HASH_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{beginKeywords:"run cmd entrypoint volume add copy workdir label healthcheck shell",starts:{end:/[^\\]$/,subLanguage:"bash"}}],illegal:"/}]}]}]},s={className:"string",begin:"~[A-Z](?="+s+")",contains:[{begin:/"/,end:/"/},{begin:/'/,end:/'/},{begin:/\//,end:/\//},{begin:/\|/,end:/\|/},{begin:/\(/,end:/\)/},{begin:/\[/,end:/\]/},{begin:/\{/,end:/\}/},{begin:/\/}]},r={className:"string",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:/"""/,end:/"""/},{begin:/'''/,end:/'''/},{begin:/~S"""/,end:/"""/,contains:[]},{begin:/~S"/,end:/"/,contains:[]},{begin:/~S'''/,end:/'''/,contains:[]},{begin:/~S'/,end:/'/,contains:[]},{begin:/'/,end:/'/},{begin:/"/,end:/"/}]},l={className:"function",beginKeywords:"def defp defmacro",end:/\B\b/,contains:[e.inherit(e.TITLE_MODE,{begin:n,endsParent:!0})]},o=e.inherit(l,{className:"class",beginKeywords:"defimpl defmodule defprotocol defrecord",end:/\bdo\b|$|;/}),s=[r,s,i,e.HASH_COMMENT_MODE,o,l,{begin:"::"},{className:"symbol",begin:":(?![\\s:])",contains:[r,{begin:"[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?"}],relevance:0},{className:"symbol",begin:n+":(?!:)",relevance:0},{className:"number",begin:"(\\b0o[0-7_]+)|(\\b0b[01_]+)|(\\b0x[0-9a-fA-F_]+)|(-?\\b[1-9][0-9_]*(.[0-9_]+([eE][-+]?[0-9]+)?)?)",relevance:0},{className:"variable",begin:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{begin:"->"},{begin:"("+e.RE_STARTERS_RE+")\\s*",contains:[e.HASH_COMMENT_MODE,{className:"regexp",illegal:"\\n",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:"/",end:"/[a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}],relevance:0}];return{lexemes:n,keywords:a,contains:t.contains=s}}function c(e){var n={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],keywords:n,illegal:"|<-"}]}}function u(e){var n="false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",a={className:"number",begin:"\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",relevance:0};return{aliases:["jsp"],keywords:n,illegal:/<\/|#/,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"class",beginKeywords:"class interface",end:/[{;=]/,excludeEnd:!0,keywords:"class interface",illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"new throw return else",relevance:0},{className:"function",begin:"([À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(<[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(\\s*,\\s*[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*)*>)?\\s+)+"+e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:n,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"params",begin:/\(/,end:/\)/,keywords:n,relevance:0,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},a,{className:"meta",begin:"@[A-Za-z]+"}]}}function _(e){var n="<>",a="",t=/<[A-Za-z0-9\\._:-]+/,i=/\/[A-Za-z0-9\\._:-]+>|\/>/,s="[A-Za-z$_][0-9A-Za-z$_]*",r={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},l={className:"number",variants:[{begin:"\\b(0[bB][01]+)n?"},{begin:"\\b(0[oO][0-7]+)n?"},{begin:e.C_NUMBER_RE+"n?"}],relevance:0},o={className:"subst",begin:"\\$\\{",end:"\\}",keywords:r,contains:[]},c={begin:"html`",end:"",starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,o],subLanguage:"xml"}},d={begin:"css`",end:"",starts:{end:"`",returnEnd:!1,contains:[e.BACKSLASH_ESCAPE,o],subLanguage:"css"}},g={className:"string",begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE,o]},o=(o.contains=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,c,d,g,l,e.REGEXP_MODE],o.contains.concat([e.C_BLOCK_COMMENT_MODE,e.C_LINE_COMMENT_MODE]));return{aliases:["js","jsx","mjs","cjs"],keywords:r,contains:[{className:"meta",relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},{className:"meta",begin:/^#!/,end:/$/},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,c,d,g,e.C_LINE_COMMENT_MODE,e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+",contains:[{className:"type",begin:"\\{",end:"\\}",relevance:0},{className:"variable",begin:s+"(?=\\s*(-)|$)",endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]}),e.C_BLOCK_COMMENT_MODE,l,{begin:/[{,\n]\s*/,relevance:0,contains:[{begin:s+"\\s*:",returnBegin:!0,relevance:0,contains:[{className:"attr",begin:s,relevance:0}]}]},{begin:"("+e.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.REGEXP_MODE,{className:"function",begin:"(\\(.*?\\)|"+s+")\\s*=>",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:s},{begin:/\(\s*\)/},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:r,contains:o}]}]},{className:"",begin:/\s/,end:/\s*/,skip:!0},{variants:[{begin:n,end:a},{begin:t,end:i}],subLanguage:"xml",contains:[{begin:t,end:i,skip:!0,contains:["self"]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/\{/,excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:s}),{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,contains:o}],illegal:/\[|%/},{begin:/\$[(.]/},e.METHOD_GUARD,{className:"class",beginKeywords:"class",end:/[{;=]/,excludeEnd:!0,illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"constructor get set",end:/\{/,excludeEnd:!0}],illegal:/#(?!!)/}}function m(e){var n={literal:"true false null"},a=[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],t=[e.QUOTE_STRING_MODE,e.C_NUMBER_MODE],i={end:",",endsWithParent:!0,excludeEnd:!0,contains:t,keywords:n},s={begin:"{",end:"}",contains:[{className:"attr",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE],illegal:"\\n"},e.inherit(i,{begin:/:/})].concat(a),illegal:"\\S"},e={begin:"\\[",end:"\\]",contains:[e.inherit(i)],illegal:"\\S"};return t.push(s,e),a.forEach(function(e){t.push(e)}),{contains:t,keywords:n,illegal:"\\S"}}function b(e){var n={keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual trait volatile transient native default",built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",literal:"true false null"},a={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@"},t={className:"subst",begin:"\\${",end:"}",contains:[e.C_NUMBER_MODE]},i={className:"string",variants:[{begin:'"""',end:'"""(?=[^"])',contains:[i={className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},t]},{begin:"'",end:"'",illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/,contains:[e.BACKSLASH_ESCAPE,i,t]}]},t=(t.contains.push(i),{className:"meta",begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?"}),s={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/,end:/\)/,contains:[e.inherit(i,{className:"meta-string"})]}]},r={className:"number",begin:"\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",relevance:0},l=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),o={variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/,contains:[]}]},c=o;return c.variants[1].contains=[o],o.variants[1].contains=[c],{aliases:["kt"],keywords:n,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,l,{className:"keyword",begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol",begin:/@\w+/}]}},a,t,s,{className:"function",beginKeywords:"fun",end:"[(]|$",returnBegin:!0,excludeEnd:!0,keywords:n,illegal:/fun\s+(<.*>)?[^\s\(]+(\s+[^\s\(]+)\s*=/,relevance:5,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin://,keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/,endsWithParent:!0,contains:[o,e.C_LINE_COMMENT_MODE,l],relevance:0},e.C_LINE_COMMENT_MODE,l,t,s,i,e.C_NUMBER_MODE]},l]},{className:"class",beginKeywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0,illegal:"extends implements",contains:[{beginKeywords:"public protected internal private constructor"},e.UNDERSCORE_TITLE_MODE,{className:"type",begin://,excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,]|$/,excludeBegin:!0,returnEnd:!0},t,s]},i,{className:"meta",begin:"^#!/usr/bin/env",end:"$",illegal:"\n"},r]}}function p(e){var n="\\[=*\\[",a="\\]=*\\]",t={begin:n,end:a,contains:["self"]},i=[e.COMMENT("--(?!"+n+")","$"),e.COMMENT("--"+n,a,{contains:[t],relevance:10})];return{lexemes:e.UNDERSCORE_IDENT_RE,keywords:{literal:"true false nil",keyword:"and break do else elseif end for goto if in local not or repeat return then until while",built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstringmodule next pairs pcall print rawequal rawget rawset require select setfenvsetmetatable tonumber tostring type unpack xpcall arg selfcoroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"},contains:i.concat([{className:"function",beginKeywords:"function",end:"\\)",contains:[e.inherit(e.TITLE_MODE,{begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params",begin:"\\(",endsWithParent:!0,contains:i}].concat(i)},e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string",begin:n,end:a,contains:[t],relevance:5}])}}function f(e){return{aliases:["md","mkdown","mkd"],contains:[{className:"section",variants:[{begin:"^#{1,6}",end:"$"},{begin:"^.+?\\n[=-]{2,}$"}]},{begin:"<",end:">",subLanguage:"xml",relevance:0},{className:"bullet",begin:"^\\s*([*+-]|(\\d+\\.))\\s+"},{className:"strong",begin:"[*_]{2}.+?[*_]{2}"},{className:"emphasis",variants:[{begin:"\\*.+?\\*"},{begin:"_.+?_",relevance:0}]},{className:"quote",begin:"^>\\s+",end:"$"},{className:"code",variants:[{begin:"^```\\w*\\s*$",end:"^```[ ]*$"},{begin:"`.+?`"},{begin:"^( {4}|\\t)",end:"$",relevance:0}]},{begin:"^[-\\*]{3,}",end:"$"},{begin:"\\[.+?\\][\\(\\[].*?[\\)\\]]",returnBegin:!0,contains:[{className:"string",begin:"\\[",end:"\\]",excludeBegin:!0,returnEnd:!0,relevance:0},{className:"link",begin:"\\]\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"symbol",begin:"\\]\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0}],relevance:10},{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}}function E(e){var n={keyword:"rec with let in inherit assert if else then",literal:"true false or and null",built_in:"import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation"},a={className:"subst",begin:/\$\{/,end:/}/,keywords:n},e=[e.NUMBER_MODE,e.HASH_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"string",contains:[a],variants:[{begin:"''",end:"''"},{begin:'"',end:'"'}]},{begin:/[a-zA-Z0-9-_]+(\s*=)/,returnBegin:!0,relevance:0,contains:[{className:"attr",begin:/\S+/}]}];return{aliases:["nixos"],keywords:n,contains:a.contains=e}}function N(e){return{disableAutodetect:!0}}function h(e){var n=/[a-zA-Z@][a-zA-Z0-9_]*/,a="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],keywords:{keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},lexemes:n,illegal:"/,end:/$/,illegal:"\\n"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class",begin:"("+a.split(" ").join("|")+")\\b",end:"({|$)",excludeEnd:!0,keywords:a,lexemes:n,contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE,relevance:0}]}}function v(e){var n="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when",a={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:n},t={begin:"->{",end:"}"},i={variants:[{begin:/\$\d/},{begin:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{begin:/[\$%@][^\s\w{]/,relevance:0}]},s=[e.BACKSLASH_ESCAPE,a,i],i=[i,e.HASH_COMMENT_MODE,e.COMMENT("^\\=\\w","\\=cut",{endsWithParent:!0}),t,{className:"string",contains:s,variants:[{begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[",end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*\\<",end:"\\>",relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'",contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE]},{begin:"{\\w+}",contains:[],relevance:0},{begin:"-?\\w+\\s*\\=\\>",contains:[],relevance:0}]},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*",keywords:"split return print reverse grep",relevance:0,contains:[e.HASH_COMMENT_MODE,{className:"regexp",begin:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",relevance:10},{className:"regexp",begin:"(m|qr)?/",end:"/[a-z]*",contains:[e.BACKSLASH_ESCAPE],relevance:0}]},{className:"function",beginKeywords:"sub",end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$",subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}]}];return a.contains=i,{aliases:["pl","pm"],lexemes:/[\w\.]+/,keywords:n,contains:t.contains=i}}function y(e){var n={begin:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},a={className:"meta",begin:/<\?(php)?|\?>/},t={className:"string",contains:[e.BACKSLASH_ESCAPE,a],variants:[{begin:'b"',end:'"'},{begin:"b'",end:"'"},e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null})]},i={variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]};return{aliases:["php","php3","php4","php5","php6","php7"],case_insensitive:!0,keywords:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",contains:[e.HASH_COMMENT_MODE,e.COMMENT("//","$",{contains:[a]}),e.COMMENT("/\\*","\\*/",{contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.COMMENT("__halt_compiler.+?;",!1,{endsWithParent:!0,keywords:"__halt_compiler",lexemes:e.UNDERSCORE_IDENT_RE}),{className:"string",begin:/<<<['"]?\w+['"]?$/,end:/^\w+;?$/,contains:[e.BACKSLASH_ESCAPE,{className:"subst",variants:[{begin:/\$\w+/},{begin:/\{\$/,end:/\}/}]}]},a,{className:"keyword",begin:/\$this\b/},n,{begin:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{className:"function",beginKeywords:"function",end:/[;{]/,excludeEnd:!0,illegal:"\\$|\\[|%",contains:[e.UNDERSCORE_TITLE_MODE,{className:"params",begin:"\\(",end:"\\)",contains:["self",n,e.C_BLOCK_COMMENT_MODE,t,i]}]},{className:"class",beginKeywords:"class interface",end:"{",excludeEnd:!0,illegal:/[:\(\$"]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"namespace",end:";",illegal:/[\.']/,contains:[e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"use",end:";",contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"=>"},t,i]}}function w(e){var n="[ \\t\\f]*",a="("+n+"[:=]"+n+"|[ \\t\\f]+)",t="([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",i="([^\\\\:= \\t\\f\\n]|\\\\.)+",s={end:a,relevance:0,starts:{className:"string",end:/$/,relevance:0,contains:[{begin:"\\\\\\n"}]}};return{case_insensitive:!0,illegal:/\S/,contains:[e.COMMENT("^\\s*[!#]","$"),{begin:t+a,returnBegin:!0,contains:[{className:"attr",begin:t,endsParent:!0,relevance:0}],starts:s},{begin:i+a,returnBegin:!0,relevance:0,contains:[{className:"meta",begin:i,endsParent:!0,relevance:0}],starts:s},{className:"attr",relevance:0,begin:i+n+"$"}]}}function O(e){var n=e.COMMENT("#","$"),a="([A-Za-z_]|::)(\\w|::)*",t=e.inherit(e.TITLE_MODE,{begin:a}),a={className:"variable",begin:"\\$"+a},i={className:"string",contains:[e.BACKSLASH_ESCAPE,a],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/}]};return{aliases:["pp"],contains:[n,a,i,{beginKeywords:"class",end:"\\{|;",illegal:/=/,contains:[t,n]},{beginKeywords:"define",end:/\{/,contains:[{className:"section",begin:e.IDENT_RE,endsParent:!0}]},{begin:e.IDENT_RE+"\\s+\\{",returnBegin:!0,end:/\S/,contains:[{className:"keyword",begin:e.IDENT_RE},{begin:/\{/,end:/\}/,keywords:{keyword:"and case default else elsif false if in import enherits node or true undef unless main settings $string ",literal:"alias audit before loglevel noop require subscribe tag owner ensure group mode name|0 changes context force incl lens load_path onlyif provider returns root show_diff type_check en_address ip_address realname command environment hour monute month monthday special target weekday creates cwd ogoutput refresh refreshonly tries try_sleep umask backup checksum content ctime force ignore links mtime purge recurse recurselimit replace selinux_ignore_defaults selrange selrole seltype seluser source souirce_permissions sourceselect validate_cmd validate_replacement allowdupe attribute_membership auth_membership forcelocal gid ia_load_module members system host_aliases ip allowed_trunk_vlans description device_url duplex encapsulation etherchannel native_vlan speed principals allow_root auth_class auth_type authenticate_user k_of_n mechanisms rule session_owner shared options device fstype enable hasrestart directory present absent link atboot blockdevice device dump pass remounts poller_tag use message withpath adminfile allow_virtual allowcdrom category configfiles flavor install_options instance package_settings platform responsefile status uninstall_options vendor unless_system_user unless_uid binary control flags hasstatus manifest pattern restart running start stop allowdupe auths expiry gid groups home iterations key_membership keys managehome membership password password_max_age password_min_age profile_membership profiles project purge_ssh_keys role_membership roles salt shell uid baseurl cost descr enabled enablegroups exclude failovermethod gpgcheck gpgkey http_caching include includepkgs keepalive metadata_expire metalink mirrorlist priority protect proxy proxy_password proxy_username repo_gpgcheck s3_enabled skip_if_unavailable sslcacert sslclientcert sslclientkey sslverify mounted",built_in:"architecture augeasversion blockdevices boardmanufacturer boardproductname boardserialnumber cfkey dhcp_servers domain ec2_ ec2_userdata facterversion filesystems ldom fqdn gid hardwareisa hardwaremodel hostname id|0 interfaces ipaddress ipaddress_ ipaddress6 ipaddress6_ iphostnumber is_virtual kernel kernelmajversion kernelrelease kernelversion kernelrelease kernelversion lsbdistcodename lsbdistdescription lsbdistid lsbdistrelease lsbmajdistrelease lsbminordistrelease lsbrelease macaddress macaddress_ macosx_buildversion macosx_productname macosx_productversion macosx_productverson_major macosx_productversion_minor manufacturer memoryfree memorysize netmask metmask_ network_ operatingsystem operatingsystemmajrelease operatingsystemrelease osfamily partitions path physicalprocessorcount processor processorcount productname ps puppetversion rubysitedir rubyversion selinux selinux_config_mode selinux_config_policy selinux_current_mode selinux_current_mode selinux_enforced selinux_policyversion serialnumber sp_ sshdsakey sshecdsakey sshrsakey swapencrypted swapfree swapsize timezone type uniqueid uptime uptime_days uptime_hours uptime_seconds uuid virtual vlans xendomains zfs_version zonenae zones zpool_version"},relevance:0,contains:[i,n,{begin:"[a-zA-Z_]+\\s*=>",returnBegin:!0,end:"=>",contains:[{className:"attr",begin:e.IDENT_RE}]},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},a]}],relevance:0}]}}function M(e){var n={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10",built_in:"Ellipsis NotImplemented",literal:"False None True"},a={className:"meta",begin:/^(>>>|\.\.\.) /},t={className:"subst",begin:/\{/,end:/\}/,keywords:n,illegal:/#/},i={begin:/\{\{/,relevance:0},i={className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:/(u|b)?r?'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,a],relevance:10},{begin:/(u|b)?r?"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,a],relevance:10},{begin:/(fr|rf|f)'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,a,i,t]},{begin:/(fr|rf|f)"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,a,i,t]},{begin:/(u|r|ur)'/,end:/'/,relevance:10},{begin:/(u|r|ur)"/,end:/"/,relevance:10},{begin:/(b|br)'/,end:/'/},{begin:/(b|br)"/,end:/"/},{begin:/(fr|rf|f)'/,end:/'/,contains:[e.BACKSLASH_ESCAPE,i,t]},{begin:/(fr|rf|f)"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,i,t]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},s={className:"number",relevance:0,variants:[{begin:e.BINARY_NUMBER_RE+"[lLjJ]?"},{begin:"\\b(0o[0-7]+)[lLjJ]?"},{begin:e.C_NUMBER_RE+"[lLjJ]?"}]},r={className:"params",begin:/\(/,end:/\)/,contains:["self",a,s,i,e.HASH_COMMENT_MODE]};return t.contains=[i,s,a],{aliases:["py","gyp","ipython"],keywords:n,illegal:/(<\/|->|\?)|=>/,contains:[a,s,{beginKeywords:"if",relevance:0},i,e.HASH_COMMENT_MODE,{variants:[{className:"function",beginKeywords:"def"},{className:"class",beginKeywords:"class"}],end:/:/,illegal:/[${=;\n,]/,contains:[e.UNDERSCORE_TITLE_MODE,r,{begin:/->/,endsWithParent:!0,keywords:"None"}]},{className:"meta",begin:/^[\t ]*@/,end:/$/},{begin:/\b(print|exec)\(/}]}}function x(e){var n="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",a={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},t={className:"doctag",begin:"@[A-Za-z]+"},i={begin:"#<",end:">"},t=[e.COMMENT("#","$",{contains:[t]}),e.COMMENT("^\\=begin","^\\=end",{contains:[t],relevance:10}),e.COMMENT("^__END__","\\n$")],s={className:"subst",begin:"#\\{",end:"}",keywords:a},r={className:"string",contains:[e.BACKSLASH_ESCAPE,s],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{begin:"%[qQwWx]?\\(",end:"\\)"},{begin:"%[qQwWx]?\\[",end:"\\]"},{begin:"%[qQwWx]?{",end:"}"},{begin:"%[qQwWx]?<",end:">"},{begin:"%[qQwWx]?/",end:"/"},{begin:"%[qQwWx]?%",end:"%"},{begin:"%[qQwWx]?-",end:"-"},{begin:"%[qQwWx]?\\|",end:"\\|"},{begin:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{begin:/<<[-~]?'?(\w+)(?:.|\n)*?\n\s*\1\b/,returnBegin:!0,contains:[{begin:/<<[-~]?'?/},{begin:/\w+/,endSameAsBegin:!0,contains:[e.BACKSLASH_ESCAPE,s]}]}]},l={className:"params",begin:"\\(",end:"\\)",endsParent:!0,keywords:a},r=[r,i,{className:"class",beginKeywords:"class module",end:"$|;",illegal:/=/,contains:[e.inherit(e.TITLE_MODE,{begin:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{begin:"<\\s*",contains:[{begin:"("+e.IDENT_RE+"::)?"+e.IDENT_RE}]}].concat(t)},{className:"function",beginKeywords:"def",end:"$|;",contains:[e.inherit(e.TITLE_MODE,{begin:n}),l].concat(t)},{begin:e.IDENT_RE+"::"},{className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"(\\!|\\?)?:",relevance:0},{className:"symbol",begin:":(?!\\s)",contains:[r,{begin:n}],relevance:0},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{className:"params",begin:/\|/,end:/\|/,keywords:a},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*",keywords:"unless",contains:[i,{className:"regexp",contains:[e.BACKSLASH_ESCAPE,s],illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:"%r{",end:"}[a-z]*"},{begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}].concat(t),relevance:0}].concat(t);return s.contains=r,{aliases:["rb","gemspec","podspec","thor","irb"],keywords:a,illegal:/\/\*/,contains:t.concat([{begin:/^\s*=>/,starts:{end:"$",contains:l.contains=r}},{className:"meta",begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>)",starts:{end:"$",contains:r}}]).concat(r)}}function C(e){var n="([ui](8|16|32|64|128|size)|f(32|64))?",a="drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!";return{aliases:["rs"],keywords:{keyword:"abstract as async await become box break const continue crate do dyn else enum extern false final fn for if impl in let loop macro match mod move mut override priv pub ref return self Self static struct super trait true try type typeof unsafe unsized use virtual where while yield",literal:"true false Some None Ok Err",built_in:a},lexemes:e.IDENT_RE+"!?",illegal:""}]}}function S(e){var n={className:"subst",variants:[{begin:"\\$[A-Za-z0-9_]+"},{begin:"\\${",end:"}"}]},n={className:"string",variants:[{begin:'"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:'"""',end:'"""',relevance:10},{begin:'[a-z]+"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE,n]},{className:"string",begin:'[a-z]+"""',end:'"""',contains:[n],relevance:10}]},a={className:"type",begin:"\\b[A-Z][A-Za-z0-9_]*",relevance:0},t={className:"title",begin:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,relevance:0};return{keywords:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,n,{className:"symbol",begin:"'\\w[\\w\\d_]*(?!')"},a,{className:"function",beginKeywords:"def",end:/[:={\[(\n;]/,excludeEnd:!0,contains:[t]},{className:"class",beginKeywords:"class object trait type",end:/[:={\[\n;]/,excludeEnd:!0,contains:[{beginKeywords:"extends with",relevance:10},{begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[a]},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[a]},t]},e.C_NUMBER_MODE,{className:"meta",begin:"@[A-Za-z]+"}]}}function T(e){return{aliases:["console"],contains:[{className:"meta",begin:"^\\s{0,3}[/\\w\\d\\[\\]()@-]*[>%$#]",starts:{end:"$",subLanguage:"bash"}}]}}function k(e){var n=e.COMMENT("--","$");return{case_insensitive:!0,illegal:/[<>{}*]/,contains:[{beginKeywords:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment values with",end:/;/,endsWithParent:!0,lexemes:/[\w\.]+/,keywords:{keyword:"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias all allocate allow alter always analyze ancillary and anti any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound bucket buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain explode export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour hours http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lateral lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minutes minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second seconds section securefile security seed segment select self semi sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tablesample tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace window with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null unknown",built_in:"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp tinyint varchar varchar2 varying void"},contains:[{className:"string",begin:"'",end:"'",contains:[{begin:"''"}]},{className:"string",begin:'"',end:'"',contains:[{begin:'""'}]},{className:"string",begin:"`",end:"`"},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,n,e.HASH_COMMENT_MODE]},e.C_BLOCK_COMMENT_MODE,n,e.HASH_COMMENT_MODE]}}function A(e){var n={keyword:"#available #colorLiteral #column #else #elseif #endif #file #fileLiteral #function #if #imageLiteral #line #selector #sourceLocation _ __COLUMN__ __FILE__ __FUNCTION__ __LINE__ Any as as! as? associatedtype associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false fileprivate final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating open operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip"},a=e.COMMENT("/\\*","\\*/",{contains:["self"]}),t={className:"subst",begin:/\\\(/,end:"\\)",keywords:n,contains:[]},i={className:"string",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:/"""/,end:/"""/},{begin:/"/,end:/"/}]},s={className:"number",begin:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",relevance:0};return t.contains=[s],{keywords:n,contains:[i,e.C_LINE_COMMENT_MODE,a,{className:"type",begin:"\\b[A-Z][\\wÀ-ʸ']*[!?]"},{className:"type",begin:"\\b[A-Z][\\wÀ-ʸ']*",relevance:0},s,{className:"function",beginKeywords:"func",end:"{",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/}),{begin://},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:n,contains:["self",s,i,e.C_BLOCK_COMMENT_MODE,{begin:":"}],illegal:/["']/}],illegal:/\[|%/},{className:"class",beginKeywords:"struct protocol class extension enum",keywords:n,end:"\\{",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/})]},{className:"meta",begin:"(@discardableResult|@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@objcMembers|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain|@dynamicMemberLookup|@propertyWrapper)"},{beginKeywords:"import",end:/$/,contains:[e.C_LINE_COMMENT_MODE,a]}]}}function R(e){var n={className:"symbol",begin:"&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;"},a={begin:"\\s",contains:[{className:"meta-keyword",begin:"#?[a-z_][a-z1-9_-]+",illegal:"\\n"}]},t=e.inherit(a,{begin:"\\(",end:"\\)"}),i=e.inherit(e.APOS_STRING_MODE,{className:"meta-string"}),s=e.inherit(e.QUOTE_STRING_MODE,{className:"meta-string"}),r={endsWithParent:!0,illegal:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin:"",relevance:10,contains:[a,s,i,t,{begin:"\\[",end:"\\]",contains:[{className:"meta",begin:"",contains:[a,t,s,i]}]}]},e.COMMENT("\x3c!--","--\x3e",{relevance:10}),{begin:"<\\!\\[CDATA\\[",end:"\\]\\]>",relevance:10},n,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{begin:/<\?(php)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*",end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0},e.inherit(e.APOS_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0})]},{className:"tag",begin:")",end:">",keywords:{name:"style"},contains:[r],starts:{end:"",returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:")",end:">",keywords:{name:"script"},contains:[r],starts:{end:"<\/script>",returnEnd:!0,subLanguage:["actionscript","javascript","handlebars","xml"]}},{className:"tag",begin:"",contains:[{className:"name",begin:/[^\/><\s]+/,relevance:0},r]}]}}function B(e){var n="true false yes no null",a={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:"{{",end:"}}"},{begin:"%{",end:"}"}]}]};return{case_insensitive:!0,aliases:["yml","YAML","yaml"],contains:[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---s*$",relevance:10},{className:"string",begin:"[\\|>]([0-9]?[+-])?[ ]*\\n( *)[\\S ]+\\n(\\2[\\S ]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!"+e.UNDERSCORE_IDENT_RE},{className:"type",begin:"!!"+e.UNDERSCORE_IDENT_RE},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"\\-(?=[ ]|$)",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{className:"number",begin:e.C_NUMBER_RE+"\\b"},a]}}var D,L,I={};D=function(t){var a,g=[],s=Object.keys,w=Object.create(null),r=Object.create(null),O=!0,n=/^(no-?highlight|plain|text)$/i,l=/\blang(?:uage)?-([\w-]+)\b/i,i=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,M="",x="Could not find the language '{}', did you forget to load/include a language module?",C={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},o="of and for in not or if then".split(" ");function S(e){return e.replace(/&/g,"&").replace(//g,">")}function u(e){return e.nodeName.toLowerCase()}function c(e){return n.test(e)}function d(e){var n,a={},t=Array.prototype.slice.call(arguments,1);for(n in e)a[n]=e[n];return t.forEach(function(e){for(n in e)a[n]=e[n]}),a}function _(e){var i=[];return function e(n,a){for(var t=n.firstChild;t;t=t.nextSibling)3===t.nodeType?a+=t.nodeValue.length:1===t.nodeType&&(i.push({event:"start",offset:a,node:t}),a=e(t,a),u(t).match(/br|hr|img|input/)||i.push({event:"stop",offset:a,node:t}));return a}(e,0),i}function m(e,n,a){var t=0,i="",s=[];function r(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset"}function o(e){i+=""}function c(e){("start"===e.event?l:o)(e.node)}for(;e.length||n.length;){var d=r();if(i+=S(a.substring(t,d[0].offset)),t=d[0].offset,d===e){for(s.reverse().forEach(o);c(d.splice(0,1)[0]),(d=r())===e&&d.length&&d[0].offset===t;);s.reverse().forEach(l)}else"start"===d[0].event?s.push(d[0].node):s.pop(),c(d.splice(0,1)[0])}return i+S(a.substr(t))}function b(n){return n.variants&&!n.cached_variants&&(n.cached_variants=n.variants.map(function(e){return d(n,{variants:null},e)})),n.cached_variants||(function e(n){return!!n&&(n.endsWithParent||e(n.starts))}(n)?[d(n,{starts:n.starts?d(n.starts):null})]:Object.isFrozen(n)?[d(n)]:[n])}function p(e){if(a&&!e.langApiRestored){for(var n in e.langApiRestored=!0,a)e[n]&&(e[a[n]]=e[n]);(e.contains||[]).concat(e.variants||[]).forEach(p)}}function f(n,t){var i={};return"string"==typeof n?a("keyword",n):s(n).forEach(function(e){a(e,n[e])}),i;function a(a,e){(e=t?e.toLowerCase():e).split(" ").forEach(function(e){var n,e=e.split("|");i[e[0]]=[a,(n=e[0],(e=e[1])?Number(e):function(e){return-1!=o.indexOf(e.toLowerCase())}(n)?0:1)]})}}function T(t){function d(e){return e&&e.source||e}function g(e,n){return new RegExp(d(e),"m"+(t.case_insensitive?"i":"")+(n?"g":""))}function i(i){var s={},r=[],l={},a=1;function e(e,n){s[a]=e,r.push([e,n]),a+=new RegExp(n.toString()+"|").exec("").length-1+1}for(var n=0;n')+n+(a?"":M)):n:""}function r(){var e,n,a,t,i;if(!m.keywords)return S(E);for(a="",m.lexemesRe.lastIndex=e=0,n=m.lexemesRe.exec(E);n;)a+=S(E.substring(e,n.index)),t=m,i=n,i=_.case_insensitive?i[0].toLowerCase():i[0],(t=t.keywords.hasOwnProperty(i)&&t.keywords[i])?(N+=t[1],a+=s(t[0],S(n[0]))):a+=S(n[0]),e=m.lexemesRe.lastIndex,n=m.lexemesRe.exec(E);return a+S(E.substr(e))}function l(){var e,n;p+=null!=m.subLanguage?(n="string"==typeof m.subLanguage)&&!w[m.subLanguage]?S(E):(e=n?k(m.subLanguage,E,!0,b[m.subLanguage]):A(E,m.subLanguage.length?m.subLanguage:void 0),0")+'"');if("end"===n.type){e=d(n);if(null!=e)return e}return E+=a,a.length}var _=R(n);if(!_)throw console.error(x.replace("{}",n)),new Error('Unknown language: "'+n+'"');T(_);for(var m=a||_,b={},p="",f=m;f!==_;f=f.parent)f.className&&(p=s(f.className,"",!0)+p);var E="",N=0;try{for(var h,v,y=0;;){if(m.terminators.lastIndex=y,!(h=m.terminators.exec(i)))break;v=u(i.substring(y,h.index),h),y=h.index+v}for(u(i.substr(y)),f=m;f.parent;f=f.parent)f.className&&(p+=M);return{relevance:N,value:p,illegal:!1,language:n,top:m}}catch(e){if(e.message&&-1!==e.message.indexOf("Illegal"))return{illegal:!0,relevance:0,value:S(i)};if(O)return{relevance:0,value:S(i),language:n,top:m,errorRaised:e};throw e}}function A(a,e){e=e||C.languages||s(w);var t={relevance:0,value:S(a)},i=t;return e.filter(R).filter(y).forEach(function(e){var n=k(e,a,!1);n.language=e,n.relevance>i.relevance&&(i=n),n.relevance>t.relevance&&(i=t,t=n)}),i.language&&(t.second_best=i),t}function E(e){return C.tabReplace||C.useBR?e.replace(i,function(e,n){return C.useBR&&"\n"===e?"
":C.tabReplace?n.replace(/\t/g,C.tabReplace):""}):e}function N(e){var n,a,t,i,s=function(e){var n,a,t,i,s,r=e.className+" ";if(r+=e.parentNode?e.parentNode.className:"",a=l.exec(r))return(s=R(a[1]))||(console.warn(x.replace("{}",a[1])),console.warn("Falling back to no-highlight mode for this block.",e)),s?a[1]:"no-highlight";for(n=0,t=(r=r.split(/\s+/)).length;n/g,"\n"):a=e,i=a.textContent,n=s?k(s,i,!0):A(i),(a=_(a)).length&&((t=document.createElement("div")).innerHTML=n.value,n.value=m(a,_(t),i)),n.value=E(n.value),e.innerHTML=n.value,e.className=(a=e.className,t=s,i=n.language,t=t?r[t]:i,i=[a.trim()],a.match(/\bhljs\b/)||i.push("hljs"),-1===a.indexOf(t)&&i.push(t),i.join(" ").trim()),e.result={language:n.language,re:n.relevance},n.second_best&&(e.second_best={language:n.second_best.language,re:n.second_best.relevance}))}function h(){var e;h.called||(h.called=!0,e=document.querySelectorAll("pre code"),g.forEach.call(e,N))}var v={disableAutodetect:!0};function R(e){return e=(e||"").toLowerCase(),w[e]||w[r[e]]}function y(e){e=R(e);return e&&!e.disableAutodetect}return t.highlight=k,t.highlightAuto=A,t.fixMarkup=E,t.highlightBlock=N,t.configure=function(e){C=d(C,e)},t.initHighlighting=h,t.initHighlightingOnLoad=function(){window.addEventListener("DOMContentLoaded",h,!1),window.addEventListener("load",h,!1)},t.registerLanguage=function(n,e){var a;try{a=e(t)}catch(e){if(console.error("Language definition for '{}' could not be registered.".replace("{}",n)),!O)throw e;console.error(e),a=v}p(w[n]=a),a.rawDefinition=e.bind(null,t),a.aliases&&a.aliases.forEach(function(e){r[e]=n})},t.listLanguages=function(){return s(w)},t.getLanguage=R,t.requireLanguage=function(e){var n=R(e);if(n)return n;throw new Error("The '{}' language is required, but not loaded.".replace("{}",e))},t.autoDetection=y,t.inherit=d,t.debugMode=function(){O=!1},t.IDENT_RE="[a-zA-Z]\\w*",t.UNDERSCORE_IDENT_RE="[a-zA-Z_]\\w*",t.NUMBER_RE="\\b\\d+(\\.\\d+)?",t.C_NUMBER_RE="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",t.BINARY_NUMBER_RE="\\b(0b[01]+)",t.RE_STARTERS_RE="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",t.BACKSLASH_ESCAPE={begin:"\\\\[\\s\\S]",relevance:0},t.APOS_STRING_MODE={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[t.BACKSLASH_ESCAPE]},t.QUOTE_STRING_MODE={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[t.BACKSLASH_ESCAPE]},t.PHRASAL_WORDS_MODE={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},t.COMMENT=function(e,n,a){e=t.inherit({className:"comment",begin:e,end:n,contains:[]},a||{});return e.contains.push(t.PHRASAL_WORDS_MODE),e.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|XXX):",relevance:0}),e},t.C_LINE_COMMENT_MODE=t.COMMENT("//","$"),t.C_BLOCK_COMMENT_MODE=t.COMMENT("/\\*","\\*/"),t.HASH_COMMENT_MODE=t.COMMENT("#","$"),t.NUMBER_MODE={className:"number",begin:t.NUMBER_RE,relevance:0},t.C_NUMBER_MODE={className:"number",begin:t.C_NUMBER_RE,relevance:0},t.BINARY_NUMBER_MODE={className:"number",begin:t.BINARY_NUMBER_RE,relevance:0},t.CSS_NUMBER_MODE={className:"number",begin:t.NUMBER_RE+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},t.REGEXP_MODE={className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[t.BACKSLASH_ESCAPE,{begin:/\[/,end:/\]/,relevance:0,contains:[t.BACKSLASH_ESCAPE]}]},t.TITLE_MODE={className:"title",begin:t.IDENT_RE,relevance:0},t.UNDERSCORE_TITLE_MODE={className:"title",begin:t.UNDERSCORE_IDENT_RE,relevance:0},t.METHOD_GUARD={begin:"\\.\\s*"+t.UNDERSCORE_IDENT_RE,relevance:0},[t.BACKSLASH_ESCAPE,t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,t.PHRASAL_WORDS_MODE,t.COMMENT,t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,t.HASH_COMMENT_MODE,t.NUMBER_MODE,t.C_NUMBER_MODE,t.BINARY_NUMBER_MODE,t.CSS_NUMBER_MODE,t.REGEXP_MODE,t.TITLE_MODE,t.UNDERSCORE_TITLE_MODE,t.METHOD_GUARD].forEach(function(e){!function n(a){Object.freeze(a);var t="function"==typeof a;Object.getOwnPropertyNames(a).forEach(function(e){!a.hasOwnProperty(e)||null===a[e]||"object"!=typeof a[e]&&"function"!=typeof a[e]||t&&("caller"===e||"callee"===e||"arguments"===e)||Object.isFrozen(a[e])||n(a[e])});return a}(e)}),t},L="object"==typeof window&&window||"object"==typeof self&&self,void 0===I||I.nodeType?L&&(L.hljs=D({}),"function"==typeof define)&&define.amd&&define([],function(){return L.hljs}):D(I);!function(){"use strict";I.registerLanguage("asciidoc",e),I.registerLanguage("bash",n),I.registerLanguage("clojure",a),I.registerLanguage("cpp",t),I.registerLanguage("cs",i),I.registerLanguage("css",s),I.registerLanguage("diff",r),I.registerLanguage("dockerfile",l),I.registerLanguage("elixir",o),I.registerLanguage("go",c),I.registerLanguage("groovy",d),I.registerLanguage("haskell",g),I.registerLanguage("java",u),I.registerLanguage("javascript",_),I.registerLanguage("json",m),I.registerLanguage("kotlin",b),I.registerLanguage("lua",p),I.registerLanguage("markdown",f),I.registerLanguage("nix",E),I.registerLanguage("none",N),I.registerLanguage("objectivec",h),I.registerLanguage("perl",v),I.registerLanguage("php",y),I.registerLanguage("properties",w),I.registerLanguage("puppet",O),I.registerLanguage("python",M),I.registerLanguage("ruby",x),I.registerLanguage("rust",C),I.registerLanguage("scala",S),I.registerLanguage("shell",T),I.registerLanguage("sql",k),I.registerLanguage("swift",A),I.registerLanguage("xml",R),I.registerLanguage("yaml",B),[].slice.call(document.querySelectorAll("pre code.hljs[data-lang]")).forEach(function(e){I.highlightBlock(e)})}()}(); \ No newline at end of file diff --git a/pr-preview/pr-59/index.html b/pr-preview/pr-59/index.html new file mode 100644 index 0000000..4e2f087 --- /dev/null +++ b/pr-preview/pr-59/index.html @@ -0,0 +1,8 @@ + + + + + +Redirect Notice +

Redirect Notice

+

The page you requested has been relocated to rhods-intro/1.33/index.html.

diff --git a/pr-preview/pr-59/rhods-intro/1.33/appendix/appendix.html b/pr-preview/pr-59/rhods-intro/1.33/appendix/appendix.html new file mode 100644 index 0000000..4c1270f --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/appendix/appendix.html @@ -0,0 +1,164 @@ + + + + + + Appendix A :: Introduction to Red Hat OpenShift AI + + + + + +
+ +
+ +
+ +
+ +
+

Appendix A

+
+

Content for Appendix A…​

+
+
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter1/_images/architecture.svg b/pr-preview/pr-59/rhods-intro/1.33/chapter1/_images/architecture.svg new file mode 100644 index 0000000..cce8b31 --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter1/_images/architecture.svg @@ -0,0 +1,1799 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter1/_images/open-data-hub-arch.png b/pr-preview/pr-59/rhods-intro/1.33/chapter1/_images/open-data-hub-arch.png new file mode 100644 index 0000000..6dfee23 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter1/_images/open-data-hub-arch.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter1/_images/techniques.png b/pr-preview/pr-59/rhods-intro/1.33/chapter1/_images/techniques.png new file mode 100644 index 0000000..42153c8 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter1/_images/techniques.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter1/_images/workflow.svg b/pr-preview/pr-59/rhods-intro/1.33/chapter1/_images/workflow.svg new file mode 100644 index 0000000..6e4d8c7 --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter1/_images/workflow.svg @@ -0,0 +1,920 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter1/index.html b/pr-preview/pr-59/rhods-intro/1.33/chapter1/index.html new file mode 100644 index 0000000..2525ca8 --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter1/index.html @@ -0,0 +1,187 @@ + + + + + + Introduction to Red Hat OpenShift AI :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Introduction to Red Hat OpenShift AI

+
+

This chapter covers the foundational concepts of Red Hat OpenShift AI (RHOAI). +You learn how to use RHOAI to overcome the common obstacles of AI projects. +This chapter also +provides a high-level description of the RHOAI architectural components, and introduces some +important terminology required in the rest of the course.

+
+
+

Chapter goals:

+
+
+
    +
  • +

    Identify the main features of Red Hat OpenShift AI

    +
  • +
  • +

    Describe the architecture and components of Red Hat OpenShift AI

    +
  • +
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter1/section1.html b/pr-preview/pr-59/rhods-intro/1.33/chapter1/section1.html new file mode 100644 index 0000000..32ca0d7 --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter1/section1.html @@ -0,0 +1,246 @@ + + + + + + Introduction :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Introduction

+
+
+
+

Red Hat OpenShift AI (RHOAI) is a platform for data scientists, machine learning engineers, and operation teams to implement the full lifecycle of AI-based applications.

+
+
+

With RHOAI, users can gather data, use the data to train and evaluate their AI models, and serve and +monitor those models.

+
+
+

Users can also create Data Science Pipelines to implement and automate model workflows.

+
+
+
+
+

The Value of RHOAI

+
+
+

RHOAI bridges the gap between data science and engineering.

+
+
+
+
+

Obstacle 1: Many AI models do not go beyond the training stages because the teams that train these models lack the tools to deploy, deliver, and maintain AI-based systems in production.

+
+
+
+
+

To solve this problem, RHOAI helps data scientists, developers and administrators to operationalize the lifecycle of AI models and bring those models to production.

+
+
+
+
+

Obstacle 2: AI practitioners often struggle with the myriad tools, libraries, and versions to maintain during the development and maintenance of AI-based applications. Additionally, significant efforts are required to configure GPU support and drivers.

+
+
+
+
+

To solve this problem, RHOAI provides data scientists with functional ability to interact with the industry norms and standard tools of the AI/ML ecosystem.

+
+
+

RHOAI augments OpenShift with the common tools used in the AI ecosystem, including:

+
+
+
+
Jupyter Notebooks
+
+

Arguably the number one tool for data scientists. +Jupyter notebooks provide interactive/executable Python documents and shells on the browser.

+
+
Portable Working Environments
+
+

Each environment is made available as a container image. +Users can create pods based on the specific +container image that they need (e.g. Python 3.11). +RHOAI provides many of these images but users can create custom ones.

+
+
GPU-Ready Environments
+
+

RHOAI provides stable working environments that are preconfigured for CUDA and NVIDIA GPUs.

+
+
Cloud-First Model Serving
+
+

RHOAI ships with OpenVino, which allows users to serve their models right after training them, +without having to develop specific APIs.

+
+
Data Science Pipelines
+
+

Users can automate the workflow of data gathering, model training, evaluation, and release instead of performing these tasks manually.

+
+
Model Monitoring
+
+

You can monitor the performance of AI models in production with Prometheus and Grafana dashboards.

+
+
+
+
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter1/section2.html b/pr-preview/pr-59/rhods-intro/1.33/chapter1/section2.html new file mode 100644 index 0000000..f7d33a7 --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter1/section2.html @@ -0,0 +1,382 @@ + + + + + + Architecture of Red Hat OpenShift AI :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Architecture of Red Hat OpenShift AI

+
+
+
+

Red Hat OpenShift AI (RHOAI) is a unified platform for data scientists, developers, machine learning engineers, and IT operations. +It is designed to manage the complete lifecycle of AI/ML projects in the hybrid cloud.

+
+
+

As the following diagram shows, RHOAI is deployed as an operator, and includes several components to handle - AI/ML development/training, automation pipelines, and model serving:

+
+
+
+architecture +
+
+
+

The following are the main concepts and terminology as it relates to RHOAI:

+
+
+
+
Models
+
+

An AI model, machine learning model, or just model is a system or algorithm designed to simulate human capabilities, by performing tasks or making decisions that usually require human intervention. +Internally, a model is typically a probabilistic or algebraic algorithm (For example, a matrix).

+
+

In short, a model takes input data, applies the algorithm (decision tree, neural network, naive Bayes, etc.) and produces the output. +Generally, the training process repeatedly adjusts the coefficients of these algorithms until the output values are similar to the training data.

+
+
+
Notebooks
+
+

A Jupyter notebook is a web-based application that allows users to interactively create live documents that contain narrative text, executable code, and visualizations. +Jupyter notebooks are popular tool in data science and machine learning. +To run and serve notebooks, you must use a notebook execution environment, such as JupyterLab.

+
+
Workbenches
+
+

A workbench is a containerized, cloud-native data science working environment that runs on OpenShift. +Workbenches run as OpenShift pods and contain commonly used data science tools such as JupyterLab, libraries such as Tensorflow, or ready-to-use GPU capabilities. +RHOAI provides several preconfigured container images for creating workbenches.

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

To use the RHOAI GPU capabilities, the NVIDIA GPU operator must be installed.

+
+
+
+
+
+
Workbench Images
+
+

Container images are to be used as workbench containers. +RHOAI includes a number of images ready to use for different common working environments. +Each image contains a different set of libraries and versions. +PyTorch, TensorFlow, Minimal Python, or Standard Data Science are examples of these images.

+
+

You can use the provided workbench images or you can create custom workbench images adapted to your needs.

+
+
+
Persistent Storage
+
+

You can mount different storage types into a workspace to persist your work. +For example, you can use persistent volume claims.

+
+
Data Connections
+
+

A data connection is a map of configuration values for connecting workbenches to external cloud storage providers, such as AWS S3. +Data connections inject the configuration values as environment variables in the associated workbench.

+
+
Data Science Pipelines
+
+

A workflow that executes scripts or Jupyter notebooks in an automated fashion. +Pipelines are useful to standardize the data gathering - data cleaning - model training - model evaluation - model upload cycle. +Typically, a pipeline ends after the trained model has been uploaded to an S3 bucket or similar cloud storage.

+
+

To use pipelines in RHOAI, the Red Hat OpenShift Pipelines operator must be installed.

+
+
+
Model Servers
+
+

A model server can read an exported model file and serve the model in a standard API. +Model servers require a data connection to download the model files from the cloud storage.

+
+
+
+
+

RHOAI is based on the Open Data Hub upstream project. +Open Data Hub is an open source, community-driven AI platform, designed for the hybrid cloud, and built on popular AI open source tools. +RHOAI is a subset of Open Data Hub, delivered both as a cloud service or is self-managed. +RHOAI can be optionally delivered with additional independent software vendor (ISV) features. +Some major differences between RHOAI and Open Data Hub are as follows:

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Open Data HubRed Hat OpenShift AI (RHOAI)

Type

Community project

Red Hat product

Offerings

Self-managed

Self-managed, managed cloud service

Components

Community projects

Community projects + Red Hat Ecosystem Catalog

GUI

UI Dashboard integrated in OpenShift

+
+
+
+

Data Science Project Workflow

+
+
+

RHOAI provides data scientists, machine learning engineers, and application developers with a unified platform to manage the complete lifecycle of AI applications, as the following diagram shows:

+
+
+
+workflow +
+
+
+

The following workflow is common in AI/ML projects:

+
+
+
+
Ingest data
+
+

In this phase, data scientists load data into the workbench. +For example, the data scientist can upload files to the workbench, download the files from S3, query data from a database, or read a data stream. +RHOAI includes the Pandas library in many of the pre-existing workbenches. +Pandas offers functions to load data from different sources, such as CSV, JSON or SQL.

+
+

Users can also add specific data ingestion capabilities by using certified ISV ecosystem apps from the Red Hat Marketplace. +Starburst and Cloudera are examples of these integrations.

+
+
+
Preprocess data
+
+

In this phase, data scientists explore, analyze, and preprocess the data. +In a Jupyter notebook, the data scientist uses libraries such as Matplotlib, Pandas, and Numpy to plot visualizations, normalize the data, or remove outliers. +RHOAI offers workbench images that include these libraries.

+
+
Train model
+
+

In this phase, data scientists use the preprocessed data to train the model. +RHOAI provides workbench images for training models with commonly used libraries, such as TensorFlow, PyTorch, and Scikit-learn. +Some of these images also include ready-to-use GPU support, to enable faster training.

+
+
Evaluate model
+
+

After training, data scientists evaluate the performance of the trained model on test and validation subsets of the data. +These subsets are portions of the ingested data that are reserved to validate that the trained models have the ability to generalize and perform well on unseen samples.

+
+

Typically, data scientists repeat the preprocessing-training-evaluation cycle until they are satisfied with the model evaluation metrics.

+
+
+
Export and upload model
+
+

When the model is trained and evaluated, the data scientists use the configuration values of the data connection to upload the files to the model storage, which can be an S3 bucket. +This step also involves the conversion of the model into a suitable format for serving, such as ONNX.

+
+
Pipeline execution
+
+

Machine Learning engineers can build data science pipelines to automatically run the previous series of steps, for example, when new data is available. +RHOAI provides data science pipelines as a combination of Tekton, Kubeflow Pipelines, and Elyra. +Engineers can choose whether they want to work at a high, visual level, by creating the pipelines with Elyra, +or at a lower lever, by using deeper Tekton and Kubeflow knowledge.

+
+
Deploy model
+
+

Machine Learning engineers can create model servers that fetch exported model from external S3 storage, and expose the model through a REST or a gRPC interface. +The model server uses a data connection to download the model files from S3.

+
+
Monitor model
+
+

Machine learning engineers and data scientists can monitor the performance of a model in production by using the metrics gathered with Prometheus.

+
+
Develop and deploy applications
+
+

After the model is available in production, application developers can develop and deploy intelligent applications that use the deployed models, by pointing their applications to the REST/gRPC interfaces of the model server.

+
+
+
+
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter1/section3.html b/pr-preview/pr-59/rhods-intro/1.33/chapter1/section3.html new file mode 100644 index 0000000..83b093b --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter1/section3.html @@ -0,0 +1,209 @@ + + + + + + Conclusion :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Conclusion

+
+
+
+

In this chapter, you learned:

+
+
+
    +
  • +

    RHOAI helps teams bridge gap between data science and engineering, by operationalizing the lifecycle of AI projects.

    +
  • +
  • +

    RHOAI is based on the upstream open source Open Data Hub project.

    +
  • +
  • +

    RHOAI provides users with ready-to-use environments that include stable versions of the most common AI/ML tools.

    +
  • +
  • +

    Users can seamlessly run training pipelines, deploy, and monitor their models in production environments.

    +
  • +
+
+
+
+
+

Next Steps

+
+
+
    +
  • +

    Create data science projects and workbenches

    +
  • +
  • +

    Use the features of workbenches and data science projects

    +
  • +
  • +

    Use Jupyter Notebook in workbenches

    +
  • +
+
+
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/create-ds-project.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/create-ds-project.png new file mode 100644 index 0000000..5fe1f40 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/create-ds-project.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/created-workbench.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/created-workbench.png new file mode 100644 index 0000000..0f29551 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/created-workbench.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/dataconnection-edit.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/dataconnection-edit.png new file mode 100644 index 0000000..6c53945 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/dataconnection-edit.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/dataconnection-list.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/dataconnection-list.png new file mode 100644 index 0000000..f40a50f Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/dataconnection-list.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/dataconnection-new.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/dataconnection-new.png new file mode 100644 index 0000000..095bb53 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/dataconnection-new.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/ds-project-dashboard.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/ds-project-dashboard.png new file mode 100644 index 0000000..5f0b9dc Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/ds-project-dashboard.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/ds-project-delete.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/ds-project-delete.png new file mode 100644 index 0000000..f80c66e Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/ds-project-delete.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/ds-project-permissions.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/ds-project-permissions.png new file mode 100644 index 0000000..aba605e Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/ds-project-permissions.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/git-clone-menu.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/git-clone-menu.png new file mode 100644 index 0000000..ace59c9 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/git-clone-menu.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/jupyterlab-home.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/jupyterlab-home.png new file mode 100644 index 0000000..72ba617 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/jupyterlab-home.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/lab-env-vars.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/lab-env-vars.png new file mode 100644 index 0000000..576ea3d Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/lab-env-vars.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/lab-test-connection.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/lab-test-connection.png new file mode 100644 index 0000000..9970ab4 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/lab-test-connection.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/lab-test-env-vars.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/lab-test-env-vars.png new file mode 100644 index 0000000..2a6107e Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/lab-test-env-vars.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/ocp-top-bar.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/ocp-top-bar.png new file mode 100644 index 0000000..6552b9c Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/ocp-top-bar.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/rhoai-create-project.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/rhoai-create-project.png new file mode 100644 index 0000000..865efbc Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/rhoai-create-project.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/rhoai-create-workbench.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/rhoai-create-workbench.png new file mode 100644 index 0000000..c643622 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/rhoai-create-workbench.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/rhoai-intro-workbench.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/rhoai-intro-workbench.png new file mode 100644 index 0000000..bc3808e Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/rhoai-intro-workbench.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/rhods-side-menu.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/rhods-side-menu.png new file mode 100644 index 0000000..d4bbb9f Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/rhods-side-menu.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-auth.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-auth.png new file mode 100644 index 0000000..a6eff7c Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-auth.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-create.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-create.png new file mode 100644 index 0000000..2f15371 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-create.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-delete.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-delete.png new file mode 100644 index 0000000..8ecfa03 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-delete.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-edit.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-edit.png new file mode 100644 index 0000000..3f04a47 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-edit.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-insufficient-resources.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-insufficient-resources.png new file mode 100644 index 0000000..bc275f6 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-insufficient-resources.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-ocp-resources.svg b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-ocp-resources.svg new file mode 100644 index 0000000..64a20dc --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-ocp-resources.svg @@ -0,0 +1,372 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-size.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-size.png new file mode 100644 index 0000000..de48c62 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-size.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-started.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-started.png new file mode 100644 index 0000000..28ab5bc Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-started.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-starting.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-starting.png new file mode 100644 index 0000000..900246d Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-starting.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-state.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-state.png new file mode 100644 index 0000000..a5a79e3 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-state.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-storage.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-storage.png new file mode 100644 index 0000000..f356c89 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-storage.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-variables.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-variables.png new file mode 100644 index 0000000..9754d6d Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-variables.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-view.png b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-view.png new file mode 100644 index 0000000..dd1b261 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter2/_images/workbench-view.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/index.html b/pr-preview/pr-59/rhods-intro/1.33/chapter2/index.html new file mode 100644 index 0000000..0d62d0f --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter2/index.html @@ -0,0 +1,182 @@ + + + + + + Working with Data Science Projects :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Working with Data Science Projects

+
+

This chapter introduces you to the initial steps and concepts required to start your projects in RHOAI. +You will learn how to use RHOAI to organize your work in data science projects. +You will also learn how to create working environments and connect those environments to storage providers.

+
+
+

Chapter goals:

+
+
+
    +
  • +

    Organize code and configuration using data science projects, workbenches, and data connections

    +
  • +
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/section1.html b/pr-preview/pr-59/rhods-intro/1.33/chapter2/section1.html new file mode 100644 index 0000000..9c99efd --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter2/section1.html @@ -0,0 +1,312 @@ + + + + + + Data Science Projects :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Data Science Projects

+
+
+
+

In RHOAI, a data science project is the preferred way to organize resources when working on an AI/ML application. +Similar to how you use projects in OpenShift for other workloads, you can use, and should use data science projects to organize the different elements that you need for your AI applications, such as workbenches, model servers, or persistent storage.

+
+
+

You can create and manage data science projects by using the RHOAI dashboard.

+
+
+

Internally, a data science project is an OpenShift project that contains specific labels to identify the project as a RHOAI-specific project, +for example:

+
+
+
+
kind: Project
+apiVersion: project.openshift.io/v1
+metadata:
+  name: my-ai-project
+  labels:
+    kubernetes.io/metadata.name: my-ai-project
+    modelmesh-enabled: 'true'
+    opendatahub.io/dashboard: 'true'
+    ...
+
+
+
+ + + + + +
+ + +
+

Regular OpenShift projects are not shown in the RHOAI dashboard.

+
+
+

If you cannot use the RHOAI dashboard, for example because you are automating the creation of your projects, then make sure that the opendatahub.io/dashboard: 'true' label is included in the project definition. +This label identifies the project as a data science project.

+
+
+

Additionally, if you wish to use model serving in your project, then you must add the modelmesh-enabled: 'true' label.

+
+
+
+
+
+
+

Exercise

+
+
+

Creating Data Science Projects

+
+

First, open the RHOAI dashboard.

+
+
+

In a web browser, navigate to the web console of your Red Hat OpenShift cluster. +You might need to enter your credentials to access the dashboard.

+
+
+

Click the applications menu in the top navigation bar of OpenShift, +then click Red Hat OpenShift AI.

+
+
+
+ocp top bar +
+
+
+

To create a data science project, click Data Science Projects in the left navigation pane.

+
+
+
+rhods side menu +
+
+
+

In the Data science projects page, click Create data science project.

+
+
+

In the modal window that opens, enter the name of the project as cat-detection and click Create.

+
+
+

You can optionally add a description and modify the OpenShift resource name for the project.

+
+
+
+create ds project +
+
+
+

After you create the project, RHOAI opens the project dashboard page.

+
+
+
+ds project dashboard +
+
+
+

From this page you can manage the project components and the permissions.

+
+
+
+

Configure Access

+
+

By default, only the project owner and privileged users can access your projects in RHOAI. +However, you can add permissions for specific users and groups.

+
+
+

To configure permissions from a project dashboard page, click the Permissions tab.

+
+
+

Here you can add users and groups, and specify their permissions.

+
+
+
+ds project permissions +
+
+
+
+

Deleting Data Science Projects

+
+

To delete a data science project, navigate to the Data science projects page.

+
+
+

Locate the project to be deleted and click its â‹® button

+
+
+

Click Delete project.

+
+
+

Finally, type the project name to confirm the deletion.

+
+
+
+ds project delete +
+
+
+
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/section2.html b/pr-preview/pr-59/rhods-intro/1.33/chapter2/section2.html new file mode 100644 index 0000000..73252a7 --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter2/section2.html @@ -0,0 +1,643 @@ + + + + + + Workbenches :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Workbenches

+
+
+
+

In RHOAI, a workbench is a containerized working environment that runs as any other application in OpenShift, as a pod. +Workbenches typically include a collection of common AI/ML libraries and a JupyterLab server. +RHOAI exposes the JupyterLab URL through an OpenShift route so that you can use and interact with the workbench via the web browser.

+
+
+

Workbenches are stateful, meaning that you can stop and restart them without losing your work.

+
+
+

Data science projects can include more than one workbench. +This is useful when you need to run different experiments that belong to the same project, but with different tooling. +For example, you might want to train a simple model with scikit-learn and another model with PyTorch. +Or you might have a workbench only for data exploration and another workbench for model training.

+
+
+
+
+

Exercise: Getting Started with Workbenches

+
+
+

Creating Workbenches

+
+

Create a data science project (or use an existing one) and navigate to the project dashboard page.

+
+
+

From this page, click Create workbench.

+
+
+

In the workbench creation page, enter the workbench name, select the workbench image, and the image version.

+
+
+

For this particular example, use the recommended version of the Minimal Python image.

+
+
+
+workbench create +
+
+
+ + + + + +
+ + +
+

The requirements of your project dictate the image that best suits your needs. +For example, if you plan to use TensorFlow, then you might want to select the TensorFlow image. +You can view more details about the selected image by clicking View package information.

+
+
+
+
+

Next, select the workbench container size. +Select Small in this case.

+
+
+
+workbench size +
+
+
+
+

Define Environment Variables

+
+

Environment variables are the recommended way to inject configuration into software applications. +In this way, the application, or in this case the RHOAI workbench, is decoupled from the working environment.

+
+
+

Scroll down to the Environment variables section and click Add variable.

+
+
+

Choose whether you want to create a ConfigMap or a Secret.

+
+
+

You can define multiple key/value pairs or upload a file.

+
+
+
+workbench variables +
+
+
+

Each ConfigMap or Secret can contain multiple key/value items.

+
+
+

To add more items to a ConfigMap or a Secret, click Add another key / value pair.

+
+
+

Alternatively, you can upload a file that includes multiple key/value pairs.

+
+
+
+

Add Storage

+
+

Workbenches require persistent storage to ensure that your progress is not lost when you stop or remove the workbench.

+
+
+

Scroll down to the Cluster storage section.

+
+
+

Verify that RHOAI automatically selects the Create new persistent storage option.

+
+
+

This is the default behavior. +RHOAI creates a dedicated persistent storage for each workbench and mounts the storage in the root directory of the container.

+
+
+

Alternatively, you can select an already existing storage. +The existing storage must not be associated with any other workbench.

+
+
+

You can adjust the storage size, which by default is 20 GiB.

+
+
+
+workbench storage +
+
+
+ + + + + +
+ + +
+

You can also create persistent storage items from the data science project page, and leave the storage unassigned. +This is useful to create persistent storage that you plan to mount in workbench directories different from /.

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

You cannot decrease the storage size of storage that is associated to a workbench.

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

You cannot delete a storage item if it is assigned to a workbench. +The storage must be unassigned if you want to delete it.

+
+
+
+
+
+

Create the Workbench

+
+

Scroll down to the bottom of the page.

+
+
+

The Data connections section lets you inject S3 connection parameters into your workbench. +Leave this section unchanged. +Data connections are covered later in the course.

+
+
+

Click Create workbench. +RHOAI triggers the creation of the workbench and redirects you to the data science project page. +While RHOAI is provisioning the workbench, the workbench displays with the Starting…​ status.

+
+
+
+workbench starting +
+
+
+

If the workbench creation is successful, then you should see the workbench running in the project dashboard. +The dashboard should also display the persistent storage associated with the workbench.

+
+
+
+workbench started +
+
+
+
+

Inspect the Workbench

+
+

In the data science project page, click the > icon to view more details about the workbench.

+
+
+

The card that slides down displays the workbench details, including storage usage.

+
+
+

You can use the Add storage button to add more storage mount points to the workbench.

+
+
+
+workbench view +
+
+
+
+

Open the Workbench

+
+

Click Open. +On the browser tab that opens, enter your credentials to authenticate to the workbench’s JupyterLab.

+
+
+

Next, allow the selected permissions to access JupyterLab.

+
+
+

Click Allow selected permissions.

+
+
+
+workbench auth +
+
+
+

Verify that you see the JupyterLab application:

+
+
+
+jupyterlab home +
+
+
+

In the right pane, click the Terminal item to open a new terminal.

+
+
+

In the terminal, verify that the DATA_FILE environment variable has been injected into the workbench:

+
+
+
+
(app-root) (app-root) echo $DATA_FILE
+data.csv
+
+
+
+

Next, create a file. +You will use this file to verify that the state of the workbench is preserved after a restart.

+
+
+
+
(app-root) (app-root) touch hello.txt
+(app-root) (app-root)
+
+
+
+
+

Starting and stopping workbenches

+
+

Return to the RHOAI data science project page. +Click the Status switch of the workbench to stop it. +The workbench status changes to Stopping…​.

+
+
+

After the workbench is stopped, toggle the switch to start the workbench again. +The workbench status changes to Starting…​.

+
+
+

When the workbench is running, switch to the JupyterLab browser tab. +You might see a message indicating that the server is unavailable. +Press F5 to refresh the page.

+
+
+

Verify that the hello.txt file that you created still exists.

+
+
+
+workbench state +
+
+
+
+

Edit the Workbench

+
+

Return to the RHOAI data science project page.

+
+
+

Click the workbench â‹® button, then click Edit workbench.

+
+
+
+workbench edit +
+
+
+

Switch the image to Standard Data Science and click Update workbench.

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

Make sure that you save your work at JupyterLab before updating a workbench.

+
+
+

When you edit a workbench, RHOAI restarts the workbench, so any unsaved work will be lost.

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

You cannot edit a workbench while the workbench is starting or stopping.

+
+
+
+
+
+

Delete the Workbench

+
+

From the project dashboard, click the workbench â‹® button

+
+
+

Click Delete workbench.

+
+
+

In the delete window, type the workbench name to confirm the operation:

+
+
+
+workbench delete +
+
+
+ + + + + +
+ + +
+

Deleting a workbench does not delete the associated persistent storage. +This means that you can create another workbench and restore the data that you were using in the previous workbench.

+
+
+
+
+
+
+
+

Workbench Resources

+
+
+

RHOAI internally defines workbenches as stateful applications. +When you create a workbench, RHOAI creates a StatefulSet in the OpenShift namespace that corresponds to your data science project. +The StatefulSet manages a pod that includes two containers:

+
+
+
    +
  • +

    The workbench container, which contains JupyterLab and other packages. +You interact with this container when you use the JupyterLab web interface.

    +
  • +
  • +

    The oauth-proxy container, which provides authorization and authentication to access JupyterLab.

    +
  • +
+
+
+

RHOAI also creates the required services and route to allow external traffic into the workbench container. +If you list the resources of the OpenShift namespace that corresponds to your data science project, you should see something similar to this:

+
+
+
+
NAME                       READY   STATUS    ..
+pod/my-first-workbench-0   2/2     Running   ..
+
+NAME                             TYPE        ...
+service/modelmesh-serving        ClusterIP   ...
+service/my-first-workbench       ClusterIP   ...
+service/my-first-workbench-tls   ClusterIP   ...
+
+NAME                                  READY  ...
+statefulset.apps/my-first-workbench   1/1    ...
+
+NAME                                         ...
+route.route.openshift.io/my-first-workbench  ...
+
+
+
+ + + + + +
+ + +
+

A single HTTPS route is created with non-secure traffic (HTTP port 80) configured to be redirected to the HTTPS port 443 (insecureEdgeTerminationPolicy: Redirect).

+
+
+
+
+

Creating a new persistent storage in RHOAI results in the creation of a PersistentVolumeClaim (PVC) in the corresponding OpenShift project. +The following diagram represents the OpenShift resources involved in a workbench:

+
+
+
+workbench ocp resources +
+
+
+ + + + + +
+ + +
+

If you delete the PVC of a storage assigned to a running workbench, then the PVC switches to Terminating state until you stop the workbench.

+
+
+
+
+
+
+

Permissions

+
+
+

To enable workbench access to other users, you must grant permissions to those users at the data science project level. +RHOAI does not offer workbench-level permission management.

+
+
+
+
+

Limits

+
+
+

If your memory and/or GPU requirements are high, then RHOAI might not be able to allocate the requested resources in the workbench. +You might see a message similar to the following:

+
+
+
+workbench insufficient resources +
+
+
+

In this case, try to decrease your resource requirements by editing the workbench, or contact your RHOAI administrator.

+
+
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/section3.html b/pr-preview/pr-59/rhods-intro/1.33/chapter2/section3.html new file mode 100644 index 0000000..e4b11d9 --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter2/section3.html @@ -0,0 +1,545 @@ + + + + + + Data Connections :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Data Connections

+
+
+
+

In data science, AI, and ML environments, the availability of data is a key factor for the success of a project. +For simple projects, where a relatively small amount of data is used, you can load data by uploading files to the workbench via JupyterLab, or by making database queries from your notebooks.

+
+
+

More complex projects, however, involve larger datasets. +Depending on the dataset size, uploading files or querying databases might not be a feasible solution. +Storing the data directly in your code repository is not recommended either, due to the overload that this can cause in your repository. +In fact, many source control systems include file size limits.

+
+
+

A better approach is to store the data in a dedicated storage system, and download the data into your workbench when you need it.

+
+
+

Similarly, a dedicated storage system is also required to store the artifacts that the training phase produces, i.e. the trained models. +Trained models can result in large files when you export them, so the recommendation is to store them in a dedicated storage system.

+
+
+
+
+

Data Connections are Secrets

+
+
+

RHOAI introduces the concept of data connection to define a set of configuration values that you can use to connect your workbench to storage systems. +You can use the external storage to store your datasets and your trained models.

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

Do not confuse data connections with cluster storage.

+
+
+

Cluster storage provides persistent storage for your workbench, by using PersistentVolumeClaim (PVC) objects in your cluster. +Cluster storage is used to persist your progress in the workbench.

+
+
+

Data connections are a set of configuration values that you can use to connect to storage systems.

+
+
+
+
+

RHOAI creates data connections in OpenShift as Secret objects. +RHOAI stores these secrets in the OpenShift namespace that corresponds to your data science project. +The secret associated with each data connection includes these key/value pairs:

+
+
+
    +
  • +

    AWS_ACCESS_KEY_ID

    +
  • +
  • +

    AWS_DEFAULT_REGION

    +
  • +
  • +

    AWS_S3_BUCKET

    +
  • +
  • +

    AWS_S3_ENDPOINT

    +
  • +
  • +

    AWS_SECRET_ACCESS_KEY

    +
  • +
+
+
+

You can set these values by using a web form in the RHOAI dashboard, as you will learn in the exercise.

+
+
+

Although the naming of these variables suggests the use of AWS S3, these values are only environment variables, so you decide how you use them in your notebooks. +You can use them to connect to systems such as OpenShift Data Foundation, IBM Cloud Object Storage, and AWS S3.

+
+
+

If you inspect the Secret object associated with a data connection, then you should see something similar to this definition:

+
+
+
+
apiVersion: v1
+kind: Secret
+data:
+  AWS_ACCESS_KEY_ID: ...
+  AWS_DEFAULT_REGION: ...
+  AWS_S3_BUCKET: ...
+  AWS_S3_ENDPOINT: ...
+  AWS_SECRET_ACCESS_KEY: ...
+metadata:
+  annotations:
+    opendatahub.io/connection-type: s3
+    openshift.io/display-name: my-first-data-connection
+  labels:
+    opendatahub.io/dashboard: "true"
+    opendatahub.io/managed: "true"
+  name: aws-connection-my-first-data-connection
+...
+
+
+
+ + + + + +
+ + +
+

Although the opendatahub.io/connection-type annotation indicates supports for different types of data connections, the RHOAI dashboard, for now, only allows the creation of S3 data connections.

+
+
+
+
+
+
+

Using the Data Connection Environment Variables

+
+
+

When you associate a data connection to a workbench, RHOAI injects the key/value pairs of the data connection as environment variables into the workbench container.

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

RHOAI does not open a connection from the workbench to AWS S3. +You are responsible for reading and using the environment variables of the data connection in the notebook.

+
+
+
+
+

Typically, you should read the data connection variables and then use them to configure the connection to the storage system. +For S3 storage, this can be done with the boto3 library, as you will learn in the following exercise.

+
+
+

After you are connected to S3, then you can start downloading the files required for data exploration or model training.

+
+
+

Similarly, you should store your trained models in the S3 bucket that corresponds to the data connection. +In fact, storing your models in the data connection enables you to use Model Serving. +Model Serving downloads the model files from S3 by using a data connection.

+
+
+
+
+

Exercise: Getting Started with Data Connections

+
+
+

Setup

+
+

Before you start with this exercise, you must configure an S3 bucket.

+
+
+

If you do not have an S3 object store available, follow the guide to create an S3 bucket by using Minio.

+
+
+

Note that you do not necessarily have to create a Data Science project to deploy Minio, as suggested in the guide. +For the purposes of these courses, you can create you own dedicated OpenShift project to deploy the Minio instance.

+
+
+
+

Create a Workbench with a Data connection

+
+

From a data science project page, click Create Workbench.

+
+
+

Select the Standard Data Science notebook image for this workbench.

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

Make sure you use the Standard Data Science image. +This image contains the boto3 library, required for the second part of the exercise.

+
+
+
+
+

Scroll down to the Data connections section and select Use a data connection.

+
+
+

Complete the form with your S3 connection parameters.

+
+
+
+dataconnection new +
+
+
+ + + + + +
+ + +
+

For S3 buckets where the region is not relevant, such as Minio, you still have to enter a placeholder value in the Region field. +A non-empty region is required to pass boto3 validations. +Otherwise, you might get an Invalid region error.

+
+
+
+
+

To create a workbench, click Create workbench.

+
+
+

This option creates the data connection and assigns it to the workbench that you are creating.

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

Alternatively, you can add a data connection to an existing workbench by editing the workbench. Save the workbench.

+
+
+
+
+

In the data science project page, notice the newly created data connection, which is associated with the workbench.

+
+
+
+dataconnection list +
+
+
+ + + + + +
+ + +
+

The association between data connections and workbenches follows a 1 to N schema:

+
+
+
    +
  • +

    The same data connection can be used in multiple workbenches.

    +
  • +
  • +

    A workbench can have only one data connection.

    +
  • +
+
+
+
+
+
+

Edit a Data connection

+
+

Note that you can assign more workbenches to the same data connection.

+
+
+

Create new workbench.

+
+
+

Next, click the â‹® button of the data connection, then click Edit data connection.

+
+
+
+dataconnection edit +
+
+
+

You do not need to make any changes.

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

You can use the data science project page to create new data connections and assign them to existing workspaces.

+
+
+

You can also use this page to delete data connections. +Deleting a data connection that is assigned to a workbench results in a workbench restart.

+
+
+
+
+
+

Using the Data Connection in a Workbench

+
+

After you have created the data connection and assigned it to your workbench, follow these steps:

+
+
+
    +
  1. +

    Clone the demo code

    +
    +
      +
    1. +

      Open the workbench JupyterLab URL.

      +
    2. +
    3. +

      If prompted, log in with your Red Hat OpenShift credentials.

      +
    4. +
    5. +

      Click Allow selected permissions to grant the workbench access to your data science project.

      +
    6. +
    7. +

      Click the Git icon in the left sidebar of JupyterLab.

      +
    8. +
    9. +

      Click Clone a repository.

      +
      +
      +git clone menu +
      +
      +
    10. +
    11. +

      Enter https://github.com/RedHatQuickCourses/rhods-intro.git as the repository, and click Clone.

      +
    12. +
    +
    +
  2. +
  3. +

    Open and run the notebook

    +
    +
      +
    1. +

      In the file explorer, navigate to the rhods-intro/notebooks/data-connections directory.

      +
    2. +
    3. +

      Open the exercise.ipynb notebook. +This exercise covers the basic use of the boto3 library, which is the AWS SDK for Python. +This library is included in some workbench images included in RHOAI, such as Standard Data Science.

      +
    4. +
    5. +

      Follow the instructions in the notebook. +Click the first cell, then press Shift+Enter to execute the cell and move to the next one.

      +
    6. +
    7. +

      Next, execute and review the rest of the cells. +Keep pressing Shift+Enter until you reach the bottom.

      +
    8. +
    +
    +
  4. +
+
+
+
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/section4.html b/pr-preview/pr-59/rhods-intro/1.33/chapter2/section4.html new file mode 100644 index 0000000..cf0d522 --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter2/section4.html @@ -0,0 +1,368 @@ + + + + + + Demo :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Demo

+
+

In this exercise, you will use RHOAI to train and evaluate a simple machine learning model, by using JupyterLab and other common ML libraries.

+
+
+
    +
  1. +

    Open the RHOAI dashboard.

    +
    +
      +
    1. +

      In a web browser, navigate to the web console of your Red Hat OpenShift cluster. +You might need to enter your credentials to access the dashboard.

      +
    2. +
    3. +

      Click the applications menu in the top navigation bar of OpenShift, +then click Red Hat OpenShift AI.

      +
      +
      +ocp top bar +
      +
      +
    4. +
    5. +

      If prompted, log in with your Red Hat OpenShift cluster credentials.

      +
    6. +
    +
    +
  2. +
  3. +

    Configure the workbench of your data science project.

    +
    +

    A RHOAI workbench is a containerized application that includes commonly used data science tools and libraries, such as JupyterLab, TensorFlow, and PyTorch. +RHOAI provides you with a collection of workbench container images, each one preconfigured and tailored to a specific data science use case.

    +
    +
    +
      +
    1. +

      Click Data Science Projects in the left sidebar.

      +
      +
      +rhods side menu +
      +
      +
    2. +
    3. +

      Create a data science project.

      +
      +

      Click Create data science project.

      +
      +
      +

      In the modal window that opens, enter a name and click Create.

      +
      +
      +
      +rhoai create project +
      +
      +
      + + + + + +
      + + +
      +

      If you are using Red Hat OpenShift from the developer sandbox, then a project is already created for you.

      +
      +
      +
      +
    4. +
    5. +

      Click the newly created project.

      +
    6. +
    7. +

      In the project page, click Create workbench and complete the form with the following values.

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

      Name

      intro

      Notebook image - Image selection

      TensorFlow

      Notebook image - Version selection

      Select the recommended option

      +
      +

      Do not modify the default values of the rest of the fields. For example,

      +
      +
      +
      +rhoai create workbench +
      +
      +
    8. +
    9. +

      Click Create workbench.

      +
      +

      RHOAI creates the workbench and the associated persistent storage.

      +
      +
      +
      +created workbench +
      +
      +
    10. +
    +
    +
  4. +
  5. +

    Open the workbench and clone the demo code.

    +
    +
      +
    1. +

      Make sure that the intro workbench is running and click Open.

      +
      +
      +rhoai intro workbench +
      +
      +
    2. +
    3. +

      If prompted, log in with your Red Hat OpenShift credentials.

      +
    4. +
    5. +

      Click Allow selected permissions to grant the workbench access to your data science project.

      +
    6. +
    7. +

      Verify that the JupyterLab interface opens in a new browser tab.

      +
    8. +
    9. +

      Click the Git icon in the left sidebar.

      +
    10. +
    11. +

      Click Clone a repository.

      +
      +
      +git clone menu +
      +
      +
    12. +
    13. +

      Enter https://github.com/RedHatQuickCourses/rhods-qc-apps.git as the repository, and click Clone.

      +
    14. +
    +
    +
  6. +
  7. +

    Open and run the notebook.

    +
    +
      +
    1. +

      In the file explorer, navigate to the rhods-qc-apps/1.intro/chapter1/intro-demo directory.

      +
    2. +
    3. +

      To open the notebook, double click notebook.ipynb. +The notebook includes instructions and code. +This is a minimal example about how you can use common data science libraries in RHOAI to train an AI model.

      +
    4. +
    5. +

      Click the first cell, then press Shift+Enter to execute the cell and move to the next one.

      +
    6. +
    7. +

      Execute and review the rest of the cells. +Keep pressing Shift+Enter until you reach the bottom.

      +
    8. +
    +
    +
  8. +
  9. +

    Run the intro-text-generation notebook

    +
    +
      +
    1. +

      In the data science project dashboard, create a new workbench with the default image for PyTorch.

      +
    2. +
    3. +

      In the new workbench, open JupyterLab and clone the https://github.com/RedHatQuickCourses/rhods-qc-apps.git repository as you did in the previous step. +This demo shows you how to fine-tune a pretrained language model for text generation by using Causal language modeling.

      +
    4. +
    5. +

      Open the rhods-qc-apps/1.intro/chapter1/intro-text-generation/notebook.ipynb notebook in JupyterLab and execute the steps. +The instructions are embedded in the notebook.

      +
    6. +
    +
    +
  10. +
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter2/section5.html b/pr-preview/pr-59/rhods-intro/1.33/chapter2/section5.html new file mode 100644 index 0000000..f3f89ac --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter2/section5.html @@ -0,0 +1,462 @@ + + + + + + Assessment Lab: Working with Data Science Projects :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Assessment Lab: Working with Data Science Projects

+
+
+
+

In this lab, you will practice the use of data science projects, permissions, workbenches, environment variables, and data connections.

+
+
+
+
+

Prerequisites

+
+
+

To perform this lab, ensure that your platform meets the following conditions:

+
+
+
    +
  • +

    An S3 bucket. If you do not have an S3 object store available, follow the guide to create an S3 bucket by using Minio.

    +
  • +
  • +

    The data-scientists user group exists in OpenShift.

    +
    +

    To create the data-scientists group, log in as a user with administrator privilege in OpenShift and then apply the https://raw.githubusercontent.com/RedHatQuickCourses/rhods-qc-apps/main/1.intro/chapter2/lab/group.yaml file:

    +
    +
    +
    +
    apiVersion: user.openshift.io/v1
    +kind: Group
    +metadata:
    +  name: data-scientists
    +users:
    +  - user4
    +  - user5
    +
    +
    +
    +

    If you use the oc CLI in your computer or terminal from OpenShift web console, then you can run:

    +
    +
    +
    +
    $ oc create -f \
    +https://raw.githubusercontent.com/RedHatQuickCourses/rhods-qc-apps/main/1.intro/chapter2/lab/group.yaml
    +
    +
    +
  • +
  • +

    The user4 and user5 users exist in OpenShift and are assigned to the data-scientists group.

    +
  • +
  • +

    The oc CLI installed on your computer. +Alternatively, you can use the OpenShift web console.

    +
  • +
+
+
+

The identity provider of your demo platform already includes these users (user4 and user5).

+
+
+
+
+
+
+

Specifications

+
+
+
    +
  • +

    Create two data science projects as user1: intro-projects-a and intro-projects-b.

    +
  • +
  • +

    Create a workbench in intro-projects-a.

    +
    +
      +
    • +

      Use the Standard Data Science image.

      +
    • +
    • +

      This workbench must be connected to the S3 bucket that is available in your demo platform.

      +
    • +
    • +

      Clone the https://github.com/RedHatQuickCourses/rhods-qc-apps repository in this workbench.

      +
    • +
    • +

      Execute the rhods-qc-apps/1.intro/chapter2/lab/test_connection.ipynb notebook in this workbench. +This notebook contains code to verify that the connection to S3.

      +
    • +
    +
    +
  • +
  • +

    Create a workbench in intro-projects-b.

    +
    +
      +
    • +

      Select any image for this workbench.

      +
    • +
    • +

      Pass your name in the STUDENT_NAME environment variable.

      +
    • +
    • +

      Clone the https://github.com/RedHatQuickCourses/rhods-qc-apps repository in this workbench.

      +
    • +
    • +

      Execute the rhods-qc-apps/1.intro/chapter2/lab/test_env_vars.ipynb notebook in this workbench. +This notebook contains code to read the environment variable.

      +
    • +
    +
    +
  • +
  • +

    The data-scientists group must have edit permissions in intro-projects-a.

    +
  • +
  • +

    Only the user4 user must have edit permissions in intro-projects-b.

    +
  • +
+
+
+
+
+

Solution

+
+
+
    +
  1. +

    Create the projects.

    +
    +
      +
    1. +

      Login as the user1 to Red Hat OpenShift AI console.

      +
    2. +
    3. +

      From your RHOAI dashboard, click Data Science Projects in the left navigation pane.

      +
    4. +
    5. +

      In the Data science projects page, click Create data science project.

      +
    6. +
    7. +

      Enter intro-projects-a as the project name and click Create.

      +
    8. +
    9. +

      Repeat the same steps to create intro-projects-b.

      +
    10. +
    +
    +
  2. +
  3. +

    Create a workbench connected to S3 in intro-projects-a.

    +
    +
      +
    1. +

      Navigate the intro-projects-a dashboard and click Create workbench. +In the workbench creation page, enter the workbench name, select the workbench image as Standard Data Science image, and the image version.

      +
    2. +
    3. +

      Select Small as the container size.

      +
    4. +
    5. +

      In the Data connections section, select Use a data connection.

      +
    6. +
    7. +

      Enter the configuration values of your S3 connection.

      +
    8. +
    9. +

      Click Create workbench to finish the creation of the workbench and the data connection.

      +
    10. +
    +
    +
  4. +
  5. +

    Verify the connection of the workbench in intro-projects-a.

    +
    +
      +
    1. +

      Open the workbench of the intro-projects-a project.

      +
    2. +
    3. +

      Log in as user1 to JupyterLab and accept the access form.

      +
    4. +
    5. +

      Clone the https://github.com/RedHatQuickCourses/rhods-qc-apps repository.

      +
    6. +
    7. +

      Navigate to rhods-qc-apps/1.intro/chapter2/lab and run the test_connection.ipynb notebook. +You should see the buckets available in S3.

      +
      +
      +lab test connection +
      +
      +
    8. +
    +
    +
  6. +
  7. +

    Create a workbench that receives the STUDENT_NAME environment variable in intro-projects-b.

    +
    +
      +
    1. +

      Navigate the intro-projects-b dashboard and click Create workbench. +In the workbench creation page, enter the workbench name, select the workbench image as Standard Data Science image, and the image version.

      +
    2. +
    3. +

      Select Small as the container size.

      +
    4. +
    5. +

      In the Environment variables section, click Add variable.

      +
    6. +
    7. +

      Select Config Map as the environment variable type. +Then select Key/value.

      +
    8. +
    9. +

      Enter STUDENT_NAME as the key, and your name as the value.

      +
      +
      +lab env vars +
      +
      +
    10. +
    11. +

      Click Create workbench to finish the creation of the workbench and the data connection.

      +
    12. +
    +
    +
  8. +
  9. +

    Verify the variable injected in the workbench in intro-projects-b.

    +
    +
      +
    1. +

      Open the workbench of the intro-projects-b project.

      +
    2. +
    3. +

      Log in as user1 to JupyterLab and accept the access form.

      +
    4. +
    5. +

      Clone the https://github.com/RedHatQuickCourses/rhods-qc-apps repository.

      +
    6. +
    7. +

      Navigate to rhods-qc-apps/1.intro/chapter2/lab and run the test_env_vars.ipynb notebook. +You should see a hello message that includes your name.

      +
      +
      +lab test env vars +
      +
      +
    8. +
    +
    +
  10. +
  11. +

    Set the project permissions of intro-projects-a.

    +
    +
      +
    1. +

      Navigate the intro-projects-a dashboard and click Permissions.

      +
    2. +
    3. +

      Click Add group and enter data-scientists as the group name. +Verify that the Permission selector is set to Edit and click the ✓ button.

      +
    4. +
    5. +

      Log out and log back in with both user4 and user5 users. +Verify that both users have access to the intro-projects-a project.

      +
    6. +
    +
    +
  12. +
  13. +

    Set the project permissions of intro-projects-b.

    +
    +
      +
    1. +

      Log out and log back in as user1.

      +
    2. +
    3. +

      Navigate the intro-projects-b dashboard and click Permissions.

      +
    4. +
    5. +

      Click Add user and enter user4 as the username. +Verify that the Permission selector is set to Edit and click the ✓ button.

      +
    6. +
    7. +

      Log out and log back in with both user4 and user5 users. +Verify that user4 can access the intro-projects-b project. +Next, verify that user5 cannot access the intro-projects-b project.

      +
    8. +
    +
    +
  14. +
+
+
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-clone-menu.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-clone-menu.png new file mode 100644 index 0000000..ace59c9 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-clone-menu.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-clone-modal.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-clone-modal.png new file mode 100644 index 0000000..2667134 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-clone-modal.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-commit-changes.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-commit-changes.png new file mode 100644 index 0000000..7d8c8fe Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-commit-changes.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-diff-view.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-diff-view.png new file mode 100644 index 0000000..4e29990 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-diff-view.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-file-staged.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-file-staged.png new file mode 100644 index 0000000..d0448fd Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-file-staged.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-forbid-changes.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-forbid-changes.png new file mode 100644 index 0000000..970d536 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-forbid-changes.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-pull-change.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-pull-change.png new file mode 100644 index 0000000..d600154 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-pull-change.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-push-icon.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-push-icon.png new file mode 100644 index 0000000..e8f5c32 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-push-icon.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-track-file.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-track-file.png new file mode 100644 index 0000000..5b683f2 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-track-file.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-untracked-file.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-untracked-file.png new file mode 100644 index 0000000..9837e8c Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/git-untracked-file.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/hello-world-notebook.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/hello-world-notebook.png new file mode 100644 index 0000000..55203dc Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/hello-world-notebook.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git-changes.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git-changes.png new file mode 100644 index 0000000..7e61635 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git-changes.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git-credentials.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git-credentials.png new file mode 100644 index 0000000..ac4135d Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git-credentials.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git-push.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git-push.png new file mode 100644 index 0000000..203593b Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git-push.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git-stage.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git-stage.png new file mode 100644 index 0000000..aee0bb0 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git-stage.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git.png new file mode 100644 index 0000000..eae2e22 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-git.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-intro.mkv b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-intro.mkv new file mode 100644 index 0000000..b8e26f5 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-intro.mkv differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-notebook-create.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-notebook-create.png new file mode 100644 index 0000000..033f447 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-notebook-create.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-notebook-rename.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-notebook-rename.png new file mode 100644 index 0000000..7cccd94 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-notebook-rename.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-terminal-open.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-terminal-open.png new file mode 100644 index 0000000..faa4056 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-terminal-open.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-terminal.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-terminal.png new file mode 100644 index 0000000..1c3d68e Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/jupyter-terminal.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/workbench-packages.png b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/workbench-packages.png new file mode 100644 index 0000000..fdbcb15 Binary files /dev/null and b/pr-preview/pr-59/rhods-intro/1.33/chapter3/_images/workbench-packages.png differ diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/index.html b/pr-preview/pr-59/rhods-intro/1.33/chapter3/index.html new file mode 100644 index 0000000..e22bdc7 --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter3/index.html @@ -0,0 +1,180 @@ + + + + + + Jupyter Notebooks :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Jupyter Notebooks

+
+

This chapter introduces you to Jupyter notebooks, why they are considered a useful tool for data science, and how you can use them.

+
+
+

Chapter goals:

+
+
+
    +
  • +

    Use Jupyter notebooks to execute and test code interactively

    +
  • +
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/section1.html b/pr-preview/pr-59/rhods-intro/1.33/chapter3/section1.html new file mode 100644 index 0000000..d87dc5a --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter3/section1.html @@ -0,0 +1,436 @@ + + + + + + Introduction :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Introduction

+
+
+
+

A Jupyter notebook is a web-based application that allows users to interactively create live documents that contain narrative text, executable code, and visualizations. +Jupyter notebooks have become a popular tool for data scientists who work in data science and machine learning projects.

+
+
+

To fully understand the Jupyter ecosystem, you must understand the following three concepts:

+
+
+
+
Notebook file
+
+

A notebook file, also called Jupyter notebook, or just notebook, is a file that contains code and multimedia content, including text, images, and audio. +This files typically use the .ipynb extension.

+
+

A notebook contains cells. +These cells can contain either Markdown or executable code.

+
+
+
JupyterLab
+
+

JupyterLab is the execution environment that runs the notebook files. +It exposes a web interface for you to visualize, edit and execute the notebooks on a web browser.

+
+ + + + + +
+ + +
+

The JupyterLab predecessor was called Jupyter Notebook. +It also provided a notebook execution environment and a web interface.

+
+
+

Note that the naming of the classic Jupyter Notebook environment can lead to confusion, because the Jupyter notebook term can also refer to a notebook file.

+
+
+
+
+

There are many ways to run an execution environment for notebooks. +You can install JupyterLab with pip and run it on your computer. +You can use the JupyterLab instances included in the RHOAI workspaces. +You can use online notebook execution environments, such as Binder, Kaggle, or Google Colab.

+
+
+
Project Jupyter
+
+

This is the umbrella open source project that defines the notebook file format and develops and maintains the JupyterLab and the Jupyter Notebook environments.

+
+
+
+
+

Most of the workbench images that RHOAI provides include JupyterLab.

+
+
+

Jupyter notebooks are popular because they provide an interactive and flexible working environment for experimentation, training, documentation, and analysis. +Notebooks integrate with many popular libraries of the data science ecosystem, which enable notebooks to combine rich text with executable code examples, and visualizations.

+
+
+

The versatility of Jupyter notebooks makes them ideal for a wide range of users. +For data scientists and researchers, these features enable them to easily analyze data, and to produce reproducible and shareable work and experiments. +For educators, Jupyter notebooks are a powerful tool to create hands-on content, which can combine narrative with executable examples.

+
+
+
+
+

Cells

+
+
+

A notebook is made of blocks, called cells. +Cells can be of two types:

+
+
+
+
Markdown cells
+
+

These cells contain Markdown content and are intended to add rich text to the notebook.

+
+
Code cells
+
+

These cells contain executable code. +JupyterLab includes support for cells that run Python code, but you can add other execution environments. +These environments are called kernels.

+
+
+
+
+

The exercise bellow covers cells in more detail.

+
+
+
+
+

Kernels

+
+
+

In the context of JupyterLab (and Jupyter Notebook), a kernel is the process that runs the code cells in a notebook. +A kernel determines the language that you can execute in a notebook, which by default is Python.

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

Kernels do not execute markdown cells.

+
+
+
+
+

JupyterLab includes a Python kernel, called ipykernel. +This is the default kernel in JupyterLab, and depends on IPython, an interactive Python shell.

+
+
+

If you wish to create notebooks that contain code cells in other languages, you can explore the Kernels List. +Many of these kernels are actively maintained by the Jupyter community.

+
+
+

You can interact with kernels without JupyterLab to create your own notebook environments. +For example, the Python extension of VSCodium supports Jupyter notebooks without installing JupyterLab. +Instead, VSCodium interacts with ipykernel.

+
+
+
+
+

Exercise: Exploring Jupyter Notebooks

+
+
+

To continue learning about notebooks, open RHOAI.

+
+
+
    +
  1. +

    In a new or an existing data science project, create a Standard Data Science workbench.

    +
  2. +
  3. +

    Open the notebook and clone the https://github.com/RedHatQuickCourses/rhods-qc-apps repository.

    +
  4. +
  5. +

    Open the 1.intro/chapter3/intro/notebooks-intro.ipynb notebook and follow the instructions.

    +
  6. +
+
+
+
+
+

Exercise: Opening Terminals

+
+
+

You can also open terminals into the workbench container via JupyterLab.

+
+
+
    +
  1. +

    Open the workbench from the previous exercise. +You can also create a new one.

    +
  2. +
  3. +

    On the Launcher tab, click the Terminal card. +If the launcher tab is not open, you can open a new launcher by clicking the + tab.

    +
    +
    +jupyter terminal +
    +
    +
  4. +
  5. +

    A new terminal opens:

    +
    +
    +jupyter terminal open +
    +
    +
  6. +
+
+
+
+
+

Demo Video

+
+
+

If you cannot run the previous exercises, you can see the following demo:

+
+
+
+ +
+
+
+
+
+

Working with Git

+
+
+

You have previously used JupyterLab to clone repositories in your workbench. +You can also commit and push your changes to your remote repository.

+
+
+

After you have cloned the repository, the Git tab in JupyterLab displays information about the current repository, including the branch, the current changes and the history.

+
+
+
+jupyter git +
+
+
+

If you make any changes, the Git card displays them:

+
+
+
+jupyter git changes +
+
+
+

You can use the + icon in this area to stage your changes.

+
+
+
+jupyter git stage +
+
+
+

You can enter the commit message and the description at the bottom, and click Commit. +At this point, JupyterLab might prompt you to enter your name and email.

+
+
+

To push (and pull) changes, use the cloud icons at the top.

+
+
+
+jupyter git push +
+
+
+

At this point, JupyterLab might prompt you to enter your Git credentials. +You can select the Save my login temporarily option to cache the credentials in the workbench.

+
+
+
+jupyter git credentials +
+
+
+ + + + + +
+ + +
+

You can also work with Git by opening a terminal in JupyterLab and using the git CLI.

+
+
+
+
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/section2.html b/pr-preview/pr-59/rhods-intro/1.33/chapter3/section2.html new file mode 100644 index 0000000..d480d1a --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter3/section2.html @@ -0,0 +1,520 @@ + + + + + + Creating, Importing and Collaborating on Notebooks :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Creating, Importing and Collaborating on Notebooks

+
+
+
+

In this section, you will learn how to create, import, and share notebooks by using a Git repository.

+
+
+

The RHOAI workbench images add the Git extension to JupyterLab. +This extension adds graphical controls to interact with Git repositories via the JupyterLab interface.

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

Alternatively, you can manage your repositories by using the git CLI, by opening a terminal in JupyterLab. +Using the CLI can be useful for advanced Git commands or if you prefer a command-line interface.

+
+
+

However, bear in mind that the Git extension integrates in the JupyterLab user interface, which can improve the efficiency of your workflow. +The Git extension might be also suitable for users who are not familiar with the syntax of Git commands.

+
+
+

After all, RHOAI offers two Git interfaces at your disposal, and you do not need to choose one or the other. +In most cases, it is beneficial to integrate both options into your workflow and use the one that better adjusts to your preferences at each moment.

+
+
+
+
+
+
+

Collaborating with Git

+
+
+

Version control systems, and in particular, Git, foster collaboration in the following ways:

+
+
+
    +
  • +

    Multiple users can work on the same code base at the same time.

    +
  • +
  • +

    Users can work in features or fixes by using branches, to reduce conflicts with the main development branch.

    +
  • +
  • +

    Users can propose, review, and discuss changes by using pull requests.

    +
  • +
+
+
+

The collaboration and collective experience of developers, companies, and open sources communities has resulted in sets of good practices and rules called Git workflows. +These workflows define how teams should work together and coordinate by using Git features, such as branches and pull requests. +Some of these workflows are:

+
+ +
+
+
+

Exercise: Creating a Notebook

+
+
+
    +
  1. +

    In a new or an existing RHOAI data science project, create a Minimal Python workbench.

    +
  2. +
  3. +

    Open the JupyterLab interface of the notebook.

    +
  4. +
  5. +

    Press Ctrl+Shift+L to open a new launcher.

    +
  6. +
  7. +

    In the Notebook section, click Python 3.9.

    +
    +
    +jupyter notebook create +
    +
    +
    +

    JupyterLab creates a new Untitled.ipynb notebook file.

    +
    +
  8. +
  9. +

    Press Ctrl+S to save the notebook. +Enter a name for the notebook and click Rename.

    +
    +
    +jupyter notebook rename +
    +
    +
    +

    You have now created your first notebook.

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

    Before creating a notebook, verify that your are at the directory where you wish to create the notebook file. +Use the JupyterLab file browser to navigate to the right directory.

    +
    +
    +
    +
  10. +
+
+
+
+
+

Exercise: Importing a Notebook from Git

+
+
+
    +
  1. +

    In the same JupyterLab window, click the Git icon.

    +
  2. +
  3. +

    Click Clone a repository.

    +
    +
    +git clone menu +
    +
    +
  4. +
  5. +

    Enter https://github.com/RedHatQuickCourses/rhods-qc-apps as the repository, and click Clone.

    +
  6. +
  7. +

    Navigate to any of the subdirectories of rhods-qc-apps and double click a notebook file to open it.

    +
  8. +
+
+
+
+
+

Exercise: Creating a Notebook in a Git Repository

+
+
+
    +
  1. +

    Create a public GitHub repository with your GitHub account. +Refer to https://docs.github.com/en/get-started/quickstart/create-a-repo if you need help with this step.

    +
  2. +
  3. +

    Return to the JupyterLab window that you have used in the previous exercise. +Click the Git icon.

    +
  4. +
  5. +

    Click Clone a repository.

    +
    +
    +git clone menu +
    +
    +
  6. +
  7. +

    Enter the URL of your Git repository and click Clone.

    +
    +
    +git clone modal +
    +
    +
  8. +
  9. +

    In the file browser, navigate to the repository directory.

    +
  10. +
  11. +

    In this directory, create a notebook file called hello.ipynb. +You can follow the steps given in the first exercise of this page.

    +
  12. +
  13. +

    Add the following code in the first cell:

    +
    +
    +
    print("Hello world")
    +
    +
    +
  14. +
  15. +

    Press Ctrl+Enter to execute the cell. +Your notebook should display as follows:

    +
    +
    +hello world notebook +
    +
    +
  16. +
  17. +

    Press Ctrl+S to save the notebook. +Alternatively, you can click File  Save Notebook.

    +
  18. +
  19. +

    Click the Git tab in the side bar. +Git displays the newly added file:

    +
    +
    +git untracked file +
    +
    +
  20. +
  21. +

    Stage the hello.ipynb file. +Right click the file and click Track.

    +
    +
    +git track file +
    +
    +
    +

    The file is now staged.

    +
    +
    +
    +git file staged +
    +
    +
  22. +
  23. +

    Enter the commit message and the description at the bottom, and click Commit.

    +
    +
    +git commit changes +
    +
    +
    +

    At this point, JupyterLab prompts for the committer information. +Enter your name and email.

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

    You can also use a Git SSH key for authenticating, as explained in the GitHub Docs. +To inject the key into the workbench you have several options, which are out of the scope of this section:

    +
    +
    +
      +
    • +

      Create a specific SSH key for your workbench and add to GitHub.

      +
    • +
    • +

      Upload your local SSH key into the workbench.

      +
    • +
    • +

      Create a kubernetes Secret with the SSH key, and mount the Secret in your workbench. +You might require support from the cluster administrator for this option.

      +
    • +
    +
    +
    +
    +
  24. +
  25. +

    Push your changes to GitHub. +Click the up arrow cloud icon at the top.

    +
    +
    +git push icon +
    +
    +
    +

    At this point, JupyterLab requires you to authenticate into GitHub. +Enter your GitHub username and token.

    +
    +
    +
    +jupyter git credentials +
    +
    +
  26. +
  27. +

    Return to GitHub and verify that your repository contains the hello.ipynb file. +Notice that GitHub can render the notebook in view-only mode.

    +
  28. +
+
+
+
+
+

Pulling Changes

+
+
+

To work with the latest version of the code, you should regularly pull changes from the remote repository. +To pull changes from a remote repository, you can use the down arrow cloud icon.

+
+
+
+git pull change +
+
+
+

If you have uncommitted changes in your workbench, then you might see a message indicating that your changes forbid pulling the changes, as follows:

+
+
+
+git forbid changes +
+
+
+

To solve this problem, commit your changes in the workbench before pulling.

+
+
+

After you have committed your changes in the workbench, you might still find problems. +For example, if the remote and the local branches have diverged, then you must configure the git strategy to reconcile the branches. +Open a terminal and run the following command to configure Git to merge branches:

+
+
+
+
git config pull.rebase false
+
+
+
+

Finally, you might occasionally find conflicts if multiple contributors are working on the same branch. +In that case, JupyterLab opens the diff view, which allows you to view the differences and solve the conflicts.

+
+
+
+git diff view +
+
+
+

After you have solved the conflicts, click the Mark as resolved button at the top right.

+
+
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/section3.html b/pr-preview/pr-59/rhods-intro/1.33/chapter3/section3.html new file mode 100644 index 0000000..84f16dc --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter3/section3.html @@ -0,0 +1,288 @@ + + + + + + Customizing Workbenches :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Customizing Workbenches

+
+
+
+

RHOAI provides preconfigured notebook images to create workbenches. +Each of these images is designed to support your data science workflow in specific and popular technological stacks. +For example, if you plan to work with PyTorch, then you might want to use the PyTorch image.

+
+
+

The notebook image that you pick, however, might not include all the libraries that you need for your project. +You might need a library that is not included in any of the images, or you might need a different set of libraries. +Or perhaps, you just need a different version of a specific library, or even a different version of Python.

+
+
+

In this case, you have two options:

+
+
+
    +
  1. +

    Create a workbench from the image that is closer to your needs and then install the required packages and versions in the workbench via JuypterLab.

    +
  2. +
  3. +

    Prepare a custom notebook image and add it to RHOAI.

    +
  4. +
+
+
+

This course covers the first option. +The second option is covered in the Red Hat OpenShift AI Administration course.

+
+
+
+
+

Supported Notebook Images

+
+
+

RHOAI ships with a collection of notebooks images, which are optimized and supported by Red Hat and independent software vendors (ISVs). +These images are designed for data scientists, providing them with the necessary tools to start working quickly. +Moreover, Red Hat provides support for these images for at least one year, and releases major versions of each image typically every six months.

+
+
+

By default, RHOAI includes these images:

+
+
+
    +
  • +

    CUDA

    +
  • +
  • +

    Standard Data Science

    +
  • +
  • +

    TensorFlow

    +
  • +
  • +

    PyTorch

    +
  • +
  • +

    Minimal Python

    +
  • +
  • +

    TrustyAI

    +
  • +
+
+
+

These images are regular container images. +The source Dockerfiles for these images are available at the red-hat-data-services/notebooks GitHub repository.

+
+
+

These images are also available in the Quay.io registry at https://quay.io/organization/modh. +RHOAI tracks these images by using ImageStreams that point to the notebook images available in Quay. +You can inspect the available images by running the following command:

+
+
+
+
$ oc get imagestream -n redhat-ods-applications
+NAME                                IMAGE REPOSITORY                                                                                                                                 TAGS                                                               UPDATED
+pytorch                             default-route-openshift-image-registry.apps.rhods-internal.61tk.p1.openshiftapps.com/redhat-ods-applications/pytorch                             2023.1,1.2-cuda-11.4,2023.1-cuda-11.7 + 3 more...                  6 weeks ago
+s2i-generic-data-science-notebook   default-route-openshift-image-registry.apps.rhods-internal.61tk.p1.openshiftapps.com/redhat-ods-applications/s2i-generic-data-science-notebook   2023.1,1.2,py3.9-v2,py3.8-v1                                       6 weeks ago
+s2i-minimal-notebook                default-route-openshift-image-registry.apps.rhods-internal.61tk.p1.openshiftapps.com/redhat-ods-applications/s2i-minimal-notebook                2023.1,1.2,py3.9-v2,py3.8-v1                                       6 weeks ago
+tensorflow                          default-route-openshift-image-registry.apps.rhods-internal.61tk.p1.openshiftapps.com/redhat-ods-applications/tensorflow                          2023.1,1.2,2023.1-cuda-11.8,1.2-cuda-11.4 + 2 more...              6 weeks ago
+...
+
+
+
+

For more information about notebook images, refer to the Notebook images for data scientists section in the Red Hat OpenShift AI documentation.

+
+
+
+
+

Exercise: Customizing Workbenches with JupyterLab

+
+
+

To use JupyterLab for customizing a workbench, follow these steps:

+
+
+
    +
  1. +

    In a new or an existing data science project, create a Standard Data Science workbench.

    +
  2. +
  3. +

    In the project dashboard, click the > icon of the workbench to expand its details. +Verify the list of packages included in the workbench.

    +
    +
    +workbench packages +
    +
    +
  4. +
  5. +

    Open the workbench. +In JupyterLab, clone the https://github.com/RedHatQuickCourses/rhods-qc-apps repository.

    +
  6. +
  7. +

    Open the 1.intro/chapter3/customize/notebooks-customize.ipynb notebook and follow the instructions.

    +
  8. +
+
+
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/section4.html b/pr-preview/pr-59/rhods-intro/1.33/chapter3/section4.html new file mode 100644 index 0000000..6e26fd3 --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter3/section4.html @@ -0,0 +1,210 @@ + + + + + + Lab: Jupyter Notebooks :: Introduction to Red Hat OpenShift AI + + + + + + + +
+ +
+ +
+ +
+ +
+

Lab: Jupyter Notebooks

+
+
+
+

In this exercise, you will assess your understanding of how to effectively use Jupyter Notebooks in RHOAI to execute Python code.

+
+
+
+
+

Specifications

+
+
+
    +
  1. +

    In RHOAI, create a data science project or use an existing one.

    +
  2. +
  3. +

    Create a workbench that includes standard data science libraries.

    +
  4. +
  5. +

    Open the workbench and clone the https://github.com/RedHatQuickCourses/rhods-qc-apps repository.

    +
  6. +
  7. +

    Open the rhods-qc-apps/1.intro/chapter3/lab/notebooks-lab.ipynb file and follow the instructions.

    +
  8. +
+
+
+ + + + + +
+ + +
+

The solution notebook is available in the rhods-qc-apps/1.intro/chapter3/lab/solution directory.

+
+
+
+
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/chapter3/section5.html b/pr-preview/pr-59/rhods-intro/1.33/chapter3/section5.html new file mode 100644 index 0000000..3fd07a1 --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/chapter3/section5.html @@ -0,0 +1,198 @@ + + + + + + Summary :: Introduction to Red Hat OpenShift AI + + + + + + +
+ +
+ +
+ +
+ +
+

Summary

+
+

In this chapter, you learned:

+
+
+
    +
  • +

    Jupyter notebooks are live documents that can contain rich text, executable code, and multimedia content.

    +
  • +
  • +

    To work with notebook files, the most popular application is JupyterLab. +JupyterLab includes the web application that you interact with, as well as the running environment for notebooks.

    +
  • +
  • +

    JupyterLab executes code cells in a separate process called kernel.

    +
  • +
  • +

    By default, JupyterLab uses a kernel that runs IPython, which is a commonly used Python shell. +This kernel is called ipykernel.

    +
  • +
  • +

    RHOAI includes a running instance of JupyterLab as the main entry point of its workbenches.

    +
  • +
  • +

    You can share notebooks and collaborate with your team by using the JupyterLab Git extension. +This extension comes preinstalled in RHOAI workbenches.

    +
  • +
  • +

    You can customize your workbench and install additional packages by running Pip in notebooks via JupyterLab. +You can also use the terminal included in JupyterLab.

    +
  • +
+
+ +
+
+
+
+
+ Red Hat +
+ + + diff --git a/pr-preview/pr-59/rhods-intro/1.33/index.html b/pr-preview/pr-59/rhods-intro/1.33/index.html new file mode 100644 index 0000000..472d643 --- /dev/null +++ b/pr-preview/pr-59/rhods-intro/1.33/index.html @@ -0,0 +1,293 @@ + + + + + + Introduction to Red Hat OpenShift AI :: Introduction to Red Hat OpenShift AI + + + + + + +
+ +
+ +
+ +
+ +
+

Introduction to Red Hat OpenShift AI

+
+
+
+

Welcome to this quick course on the Introduction to Red Hat OpenShift AI. +This course is the first in a series of five courses about Red Hat OpenShift AI:

+
+ +
+ + + + + +
+ + +After you have completed all the courses in the learning path, you can attempt the "Workshop final hands-on lab", that tests your understanding of the concepts taught in all the courses. +
+
+
+ + + + + +
+ + +The hands-on labs in this course were created and tested with RHOAI v2.8.0. Labs should mostly work without any changes in minor dot release upgrades of the product. Please open issues in this repository if you face any issue. +
+
+
+
+
+

Authors

+
+
+

The PTL team acknowledges the valuable contributions of the following Red Hat associates:

+
+
+
    +
  • +

    Jaime Ramirez Castillo

    +
  • +
  • +

    Trevor Royer

    +
  • +
  • +

    Ravi Srinivasan

    +
  • +
+
+
+
+
+

Classroom Environment

+
+
+

This introductory course has a few, simple hands-on labs. You will use the Base RHOAI on AWS catalog item in the Red Hat Demo Platform (RHDP) to run the hands-on exercises in this course.

+
+
+

For Red Hat partners who do not have access to RHDP, provision an environment using the Red Hat Hybrid Cloud Console. Unfortunately, the labs will NOT work on the trial sandbox environment. You need to provision an OpenShift AI cluster on-premises, or in the supported cloud environments by following the product documentation at Product Documentation for Red Hat OpenShift AI 2024.

+
+
+

The other courses in the learning path use a different classroom. Inspect the prerequisites and +classroom requirements in the respective individual courses.

+
+
+
+
+

Prerequisites

+
+
+

For this introductory course, basic experience with Red Hat OpenShift is recommended but is not mandatory.

+
+
+
+
+

Objectives

+
+
+

The overall objectives of this introductory course include:

+
+
+
    +
  • +

    Familiarize with the general architecture and main features of Red Hat OpenShift AI

    +
  • +
  • +

    Access and log in to the Red Hat OpenShift AI web console

    +
  • +
  • +

    Create, share, and delete data science projects

    +
  • +
  • +

    Create a workbench within a data science project

    +
  • +
  • +

    Create and delete data connections

    +
  • +
  • +

    Create, import (from Git repositories), and share Jupyter Notebook

    +
  • +
  • +

    Install Python packages in your Jupyter Notebook

    +
  • +
+
+
+
+ +
+
+
+
+
+ Red Hat +
+ + +